From d5a6e82eeb9bebda9ddfee1601296fb825e93e99 Mon Sep 17 00:00:00 2001 From: Federico Mastrini Date: Mon, 6 Nov 2023 12:29:49 +0100 Subject: [PATCH 1/3] refactor: idpay data --- src/persistence/idpay.ts | 392 +++++++++++++++++++++++++-------------- 1 file changed, 257 insertions(+), 135 deletions(-) diff --git a/src/persistence/idpay.ts b/src/persistence/idpay.ts index bcf781b9..ab0e7658 100644 --- a/src/persistence/idpay.ts +++ b/src/persistence/idpay.ts @@ -2,7 +2,10 @@ import { faker } from "@faker-js/faker/locale/it"; import { range } from "lodash"; import { ulid } from "ulid"; import { IbanDTO } from "../../generated/definitions/idpay/IbanDTO"; -import { OperationTypeEnum as IbanOperationEnum } from "../../generated/definitions/idpay/IbanOperationDTO"; +import { + IbanOperationDTO, + OperationTypeEnum as IbanOperationTypeEnum +} from "../../generated/definitions/idpay/IbanOperationDTO"; import { InitiativeDTO, InitiativeRewardTypeEnum, @@ -10,33 +13,51 @@ import { } from "../../generated/definitions/idpay/InitiativeDTO"; import { InstrumentDTO, - StatusEnum as InstrumentStatus, - InstrumentTypeEnum + StatusEnum as InstrumentStatus } from "../../generated/definitions/idpay/InstrumentDTO"; -import { OperationTypeEnum as InstrumentOperationEnum } from "../../generated/definitions/idpay/InstrumentOperationDTO"; -import { OperationTypeEnum as OnboardingOperationEnum } from "../../generated/definitions/idpay/OnboardingOperationDTO"; +import { + InstrumentOperationDTO, + OperationTypeEnum as InstrumentOperationTypeEnum, + InstrumentTypeEnum +} from "../../generated/definitions/idpay/InstrumentOperationDTO"; +import { + OnboardingOperationDTO, + OperationTypeEnum as OnboardingOperationTypeEnum +} from "../../generated/definitions/idpay/OnboardingOperationDTO"; import { OperationListDTO } from "../../generated/definitions/idpay/OperationListDTO"; -import { OperationTypeEnum as RefundOperationEnum } from "../../generated/definitions/idpay/RefundOperationDTO"; +import { + ReadmittedOperationDTO, + OperationTypeEnum as ReadmittedOperationTypeEnum +} from "../../generated/definitions/idpay/ReadmittedOperationDTO"; +import { + RefundOperationDTO, + OperationTypeEnum as RefundOperationTypeEnum +} from "../../generated/definitions/idpay/RefundOperationDTO"; import { InstrumentTypeEnum as OperationInstrumentTypeEnum, - OperationTypeEnum as RejectedInstrumentOperationEnum + RejectedInstrumentOperationDTO, + OperationTypeEnum as RejectedInstrumentOperationTypeEnum } from "../../generated/definitions/idpay/RejectedInstrumentOperationDTO"; +import { + SuspendOperationDTO, + OperationTypeEnum as SuspendOperationTypeEnum +} from "../../generated/definitions/idpay/SuspendOperationDTO"; import { ChannelEnum as TransactionChannelEnum, - OperationTypeEnum as TransactionOperationEnum, + TransactionOperationDTO, + OperationTypeEnum as TransactionOperationTypeEnum, StatusEnum as TransactionStatusEnum } from "../../generated/definitions/idpay/TransactionOperationDTO"; -import { CardInfo } from "../../generated/definitions/pagopa/CardInfo"; import { WalletV2 } from "../../generated/definitions/pagopa/WalletV2"; import { ioDevServerConfig } from "../config"; import { getRandomEnumValue } from "../payloads/utils/random"; import { getWalletV2 } from "../routers/walletsV2"; +import { creditCardBrands, getCreditCardLogo } from "../utils/payment"; const idPayConfig = ioDevServerConfig.features.idpay; const { idPay: walletConfig } = ioDevServerConfig.wallet; const pagoPaWallet: WalletV2 = getWalletV2()[0]; -const pagoPaWalletInfo: CardInfo = pagoPaWallet.info as CardInfo; const generateRandomInitiativeDTO = (): InitiativeDTO => { const amount = faker.datatype.number({ min: 50, max: 200, precision: 10 }); @@ -68,68 +89,114 @@ const generateRandomIbanDTO = (): IbanDTO => ({ channel: faker.datatype.string() }); -const generateRandomOperationDTO = ( - type: OperationListDTO["operationType"] -): OperationListDTO => { - switch (type) { - case "PAID_REFUND": - case "REJECTED_REFUND": - return { - operationType: type, - operationDate: new Date(), - operationId: ulid(), - eventId: ulid(), - amount: faker.datatype.number({ min: 5, max: 100 }) - }; - case "REVERSAL": - case "TRANSACTION": - return { - operationType: type, - operationDate: new Date(), - operationId: ulid(), - accrued: faker.datatype.number({ min: 5, max: 25 }), - amount: faker.datatype.number({ min: 50, max: 100 }), - brand: pagoPaWalletInfo.brand || "VISA", - circuitType: "01", - brandLogo: pagoPaWalletInfo.brandLogo || "", - maskedPan: pagoPaWalletInfo.blurredNumber || "0000", - status: getRandomEnumValue(TransactionStatusEnum), - channel: TransactionChannelEnum.RTD, - businessName: faker.company.name(), - eventId: ulid() - }; - case "ADD_IBAN": - return { - operationType: IbanOperationEnum.ADD_IBAN, - operationDate: new Date(), - operationId: ulid(), - channel: faker.datatype.string(), - iban: faker.helpers.arrayElement(ibanList)?.iban || "" - }; - case "ADD_INSTRUMENT": - case "REJECTED_ADD_INSTRUMENT": - case "DELETE_INSTRUMENT": - case "REJECTED_DELETE_INSTRUMENT": - return { - operationType: type, - operationDate: new Date(), - operationId: ulid(), - brand: pagoPaWalletInfo.brand || "VISA", - brandLogo: pagoPaWalletInfo.brandLogo || "", - channel: faker.datatype.string(), - maskedPan: pagoPaWalletInfo.blurredNumber || "0000", - instrumentType: OperationInstrumentTypeEnum.CARD - }; - case "ONBOARDING": - default: - return { - operationType: OnboardingOperationEnum.ONBOARDING, - operationDate: new Date(), - operationId: ulid() - }; - } +const generateRandomTransactionOperationDTO = ( + withInfo?: Partial +): TransactionOperationDTO => { + const brand = faker.helpers.arrayElement(creditCardBrands); + const brandLogo = getCreditCardLogo(brand); + const maskedPan = Array.from({ length: 4 }, () => + Math.floor(Math.random() * 10) + ).join(""); + + return { + operationType: getRandomEnumValue(TransactionOperationTypeEnum), + operationDate: new Date(), + operationId: ulid(), + accrued: faker.datatype.number({ min: 5, max: 25 }), + amount: faker.datatype.number({ min: 50, max: 100 }), + brand, + circuitType: "01", + brandLogo, + maskedPan, + status: getRandomEnumValue(TransactionStatusEnum), + channel: getRandomEnumValue(TransactionChannelEnum), + businessName: faker.company.name(), + eventId: ulid(), + ...withInfo + }; +}; + +const generateRandomRefundOperationDTO = ( + withInfo?: Partial +): RefundOperationDTO => ({ + operationType: getRandomEnumValue(RefundOperationTypeEnum), + operationDate: new Date(), + operationId: ulid(), + eventId: ulid(), + amount: faker.datatype.number({ min: 5, max: 100 }), + ...withInfo +}); + +const generateRandomIbanOperationDTO = (): IbanOperationDTO => ({ + operationType: IbanOperationTypeEnum.ADD_IBAN, + operationDate: new Date(), + operationId: ulid(), + channel: faker.datatype.string(), + iban: faker.helpers.arrayElement(ibanList)?.iban || "" +}); + +const generateRandomOnboardingOperationDTO = (): OnboardingOperationDTO => ({ + operationType: OnboardingOperationTypeEnum.ONBOARDING, + operationDate: new Date(), + operationId: ulid() +}); + +const generateRandomInstrumentOperationDTO = ( + withInfo?: Partial +): InstrumentOperationDTO => { + const brand = faker.helpers.arrayElement(creditCardBrands); + const brandLogo = getCreditCardLogo(brand); + const maskedPan = Array.from({ length: 4 }, () => + Math.floor(Math.random() * 10) + ).join(""); + + return { + operationType: getRandomEnumValue(InstrumentOperationTypeEnum), + operationDate: new Date(), + operationId: ulid(), + brand, + brandLogo, + channel: getRandomEnumValue(TransactionChannelEnum), + maskedPan, + instrumentType: getRandomEnumValue(OperationInstrumentTypeEnum), + ...withInfo + }; +}; + +const generateRandomRejectedInstrumentOperationDTO = ( + withInfo?: Partial +): RejectedInstrumentOperationDTO => { + const brand = faker.helpers.arrayElement(creditCardBrands); + const brandLogo = getCreditCardLogo(brand); + const maskedPan = Array.from({ length: 4 }, () => + Math.floor(Math.random() * 10) + ).join(""); + + return { + operationType: getRandomEnumValue(RejectedInstrumentOperationTypeEnum), + operationDate: new Date(), + operationId: ulid(), + brand, + brandLogo, + channel: getRandomEnumValue(TransactionChannelEnum), + maskedPan, + instrumentType: getRandomEnumValue(OperationInstrumentTypeEnum), + ...withInfo + }; }; +const generateRandomSuspendOperationDTO = (): SuspendOperationDTO => ({ + operationType: SuspendOperationTypeEnum.SUSPENDED, + operationDate: new Date(), + operationId: ulid() +}); + +const generateRandomReadmittedOperationDTO = (): ReadmittedOperationDTO => ({ + operationType: ReadmittedOperationTypeEnum.READMITTED, + operationDate: new Date(), + operationId: ulid() +}); + // eslint-disable-next-line functional/no-let export let initiatives: { [id: string]: InitiativeDTO } = {}; @@ -281,20 +348,63 @@ range(0, walletConfig.refundCount).forEach(() => { initiativeTimeline = { ...initiativeTimeline, [initiativeId]: [ - generateRandomOperationDTO(RefundOperationEnum.REJECTED_REFUND), - generateRandomOperationDTO(RefundOperationEnum.PAID_REFUND), - generateRandomOperationDTO(TransactionOperationEnum.REVERSAL), - generateRandomOperationDTO(TransactionOperationEnum.TRANSACTION), - generateRandomOperationDTO( - RejectedInstrumentOperationEnum.REJECTED_DELETE_INSTRUMENT - ), - generateRandomOperationDTO( - RejectedInstrumentOperationEnum.REJECTED_ADD_INSTRUMENT - ), - generateRandomOperationDTO(IbanOperationEnum.ADD_IBAN), - generateRandomOperationDTO(InstrumentOperationEnum.DELETE_INSTRUMENT), - generateRandomOperationDTO(InstrumentOperationEnum.ADD_INSTRUMENT), - generateRandomOperationDTO(OnboardingOperationEnum.ONBOARDING) + generateRandomRefundOperationDTO({ + operationType: RefundOperationTypeEnum.PAID_REFUND + }), + generateRandomRefundOperationDTO({ + operationType: RefundOperationTypeEnum.REJECTED_REFUND + }), + generateRandomTransactionOperationDTO({ + operationType: TransactionOperationTypeEnum.REVERSAL, + status: TransactionStatusEnum.AUTHORIZED + }), + generateRandomTransactionOperationDTO({ + operationType: TransactionOperationTypeEnum.TRANSACTION, + status: TransactionStatusEnum.CANCELLED + }), + generateRandomTransactionOperationDTO({ + operationType: TransactionOperationTypeEnum.TRANSACTION, + status: TransactionStatusEnum.AUTHORIZED, + businessName: undefined + }), + generateRandomTransactionOperationDTO({ + operationType: TransactionOperationTypeEnum.TRANSACTION, + status: TransactionStatusEnum.AUTHORIZED + }), + generateRandomIbanOperationDTO(), + generateRandomRejectedInstrumentOperationDTO({ + operationType: + RejectedInstrumentOperationTypeEnum.REJECTED_DELETE_INSTRUMENT, + instrumentType: InstrumentTypeEnum.CARD + }), + generateRandomInstrumentOperationDTO({ + operationType: InstrumentOperationTypeEnum.DELETE_INSTRUMENT, + instrumentType: InstrumentTypeEnum.CARD + }), + generateRandomInstrumentOperationDTO({ + operationType: InstrumentOperationTypeEnum.DELETE_INSTRUMENT, + instrumentType: InstrumentTypeEnum.CARD, + brand: undefined, + maskedPan: undefined + }), + generateRandomRejectedInstrumentOperationDTO({ + operationType: + RejectedInstrumentOperationTypeEnum.REJECTED_ADD_INSTRUMENT, + instrumentType: InstrumentTypeEnum.CARD + }), + generateRandomInstrumentOperationDTO({ + operationType: InstrumentOperationTypeEnum.ADD_INSTRUMENT, + instrumentType: InstrumentTypeEnum.CARD + }), + generateRandomInstrumentOperationDTO({ + operationType: InstrumentOperationTypeEnum.ADD_INSTRUMENT, + instrumentType: InstrumentTypeEnum.CARD, + brand: undefined, + maskedPan: undefined + }), + generateRandomReadmittedOperationDTO(), + generateRandomSuspendOperationDTO(), + generateRandomOnboardingOperationDTO() ] }; }); @@ -317,9 +427,7 @@ range(0, walletConfig.refundNotConfiguredCount).forEach(() => { instruments = { ...instruments, [initiativeId]: [] }; initiativeTimeline = { ...initiativeTimeline, - [initiativeId]: [ - generateRandomOperationDTO(OnboardingOperationEnum.ONBOARDING) - ] + [initiativeId]: [generateRandomOnboardingOperationDTO()] }; }); @@ -350,22 +458,7 @@ range(0, walletConfig.refundUnsubscribedCount).forEach(() => { }; initiativeTimeline = { ...initiativeTimeline, - [initiativeId]: [ - generateRandomOperationDTO(RefundOperationEnum.REJECTED_REFUND), - generateRandomOperationDTO(RefundOperationEnum.PAID_REFUND), - generateRandomOperationDTO(TransactionOperationEnum.REVERSAL), - generateRandomOperationDTO(TransactionOperationEnum.TRANSACTION), - generateRandomOperationDTO( - RejectedInstrumentOperationEnum.REJECTED_DELETE_INSTRUMENT - ), - generateRandomOperationDTO( - RejectedInstrumentOperationEnum.REJECTED_ADD_INSTRUMENT - ), - generateRandomOperationDTO(IbanOperationEnum.ADD_IBAN), - generateRandomOperationDTO(InstrumentOperationEnum.DELETE_INSTRUMENT), - generateRandomOperationDTO(InstrumentOperationEnum.ADD_INSTRUMENT), - generateRandomOperationDTO(OnboardingOperationEnum.ONBOARDING) - ] + [initiativeId]: [generateRandomOnboardingOperationDTO()] }; }); @@ -397,20 +490,22 @@ range(0, walletConfig.refundSuspendedCount).forEach(() => { initiativeTimeline = { ...initiativeTimeline, [initiativeId]: [ - generateRandomOperationDTO(RefundOperationEnum.REJECTED_REFUND), - generateRandomOperationDTO(RefundOperationEnum.PAID_REFUND), - generateRandomOperationDTO(TransactionOperationEnum.REVERSAL), - generateRandomOperationDTO(TransactionOperationEnum.TRANSACTION), - generateRandomOperationDTO( - RejectedInstrumentOperationEnum.REJECTED_DELETE_INSTRUMENT - ), - generateRandomOperationDTO( - RejectedInstrumentOperationEnum.REJECTED_ADD_INSTRUMENT - ), - generateRandomOperationDTO(IbanOperationEnum.ADD_IBAN), - generateRandomOperationDTO(InstrumentOperationEnum.DELETE_INSTRUMENT), - generateRandomOperationDTO(InstrumentOperationEnum.ADD_INSTRUMENT), - generateRandomOperationDTO(OnboardingOperationEnum.ONBOARDING) + generateRandomRefundOperationDTO({ + operationType: RefundOperationTypeEnum.PAID_REFUND + }), + generateRandomRefundOperationDTO({ + operationType: RefundOperationTypeEnum.REJECTED_REFUND + }), + generateRandomTransactionOperationDTO({ + operationType: TransactionOperationTypeEnum.TRANSACTION, + status: TransactionStatusEnum.CANCELLED + }), + generateRandomTransactionOperationDTO({ + operationType: TransactionOperationTypeEnum.TRANSACTION, + businessName: undefined + }), + generateRandomTransactionOperationDTO(), + generateRandomOnboardingOperationDTO() ] }; }); @@ -439,7 +534,7 @@ range(0, walletConfig.discountCount).forEach(() => { instrumentId: ulid(), activationDate: new Date(), status: InstrumentStatus.ACTIVE, - instrumentType: InstrumentTypeEnum.QRCODE + instrumentType: InstrumentTypeEnum.IDPAYCODE } ] }; @@ -447,26 +542,53 @@ range(0, walletConfig.discountCount).forEach(() => { initiativeTimeline = { ...initiativeTimeline, [initiativeId]: [ - { - ...generateRandomOperationDTO(TransactionOperationEnum.TRANSACTION), + generateRandomTransactionOperationDTO({ + operationType: TransactionOperationTypeEnum.TRANSACTION, status: TransactionStatusEnum.AUTHORIZED, - channel: TransactionChannelEnum.QRCODE - } as OperationListDTO, - { - ...generateRandomOperationDTO(TransactionOperationEnum.TRANSACTION), + brand: undefined + }), + generateRandomTransactionOperationDTO({ + operationType: TransactionOperationTypeEnum.TRANSACTION, + businessName: undefined, + brand: undefined + }), + generateRandomTransactionOperationDTO({ + operationType: TransactionOperationTypeEnum.TRANSACTION, + status: TransactionStatusEnum.AUTHORIZED, + channel: TransactionChannelEnum.QRCODE, + brand: undefined, + businessName: undefined + }), + generateRandomTransactionOperationDTO({ + operationType: TransactionOperationTypeEnum.TRANSACTION, + status: TransactionStatusEnum.AUTHORIZED, + channel: TransactionChannelEnum.QRCODE, + brand: undefined + }), + generateRandomTransactionOperationDTO({ + operationType: TransactionOperationTypeEnum.TRANSACTION, status: TransactionStatusEnum.REWARDED, - channel: TransactionChannelEnum.QRCODE - } as OperationListDTO, - { - ...generateRandomOperationDTO(TransactionOperationEnum.TRANSACTION), + channel: TransactionChannelEnum.QRCODE, + brand: undefined + }), + generateRandomTransactionOperationDTO({ + operationType: TransactionOperationTypeEnum.TRANSACTION, status: TransactionStatusEnum.CANCELLED, - channel: TransactionChannelEnum.QRCODE - } as OperationListDTO, - { - ...generateRandomOperationDTO(InstrumentOperationEnum.ADD_INSTRUMENT), - instrumentType: OperationInstrumentTypeEnum.IDPAYCODE - }, - generateRandomOperationDTO(OnboardingOperationEnum.ONBOARDING) + channel: TransactionChannelEnum.QRCODE, + brand: undefined + }), + generateRandomTransactionOperationDTO({ + operationType: TransactionOperationTypeEnum.REVERSAL, + status: TransactionStatusEnum.REWARDED, + channel: TransactionChannelEnum.QRCODE, + brand: undefined + }), + generateRandomInstrumentOperationDTO({ + operationType: InstrumentOperationTypeEnum.ADD_INSTRUMENT, + instrumentType: OperationInstrumentTypeEnum.IDPAYCODE, + brand: undefined + }), + generateRandomOnboardingOperationDTO() ] }; }); From d818a9a98cddf9f2e93825b8826f85c1b542a6a3 Mon Sep 17 00:00:00 2001 From: Federico Mastrini Date: Fri, 10 Nov 2023 14:16:01 +0100 Subject: [PATCH 2/3] fix: tests --- src/routers/features/idpay/__tests__/wallet.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routers/features/idpay/__tests__/wallet.test.ts b/src/routers/features/idpay/__tests__/wallet.test.ts index f279f2a6..11d7c8ab 100644 --- a/src/routers/features/idpay/__tests__/wallet.test.ts +++ b/src/routers/features/idpay/__tests__/wallet.test.ts @@ -309,7 +309,7 @@ describe("IDPay Wallet API", () => { describe("PUT enrollInstrumentCode", () => { // eslint-disable-next-line sonarjs/no-duplicate-string it("should return 200", async () => { - const tInitiative = initiatives[1]; + const tInitiative = initiatives[0]; const initiativeId = tInitiative.initiativeId; generateIdPayCode(); From 95cc603745df12dd48349d1b6a1c27bad65c58ee Mon Sep 17 00:00:00 2001 From: Federico Mastrini Date: Fri, 10 Nov 2023 20:00:14 +0100 Subject: [PATCH 3/3] fix: tests --- src/persistence/idpay.ts | 19 ++++++++++--------- .../features/idpay/__tests__/wallet.test.ts | 2 +- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/persistence/idpay.ts b/src/persistence/idpay.ts index ab0e7658..2e198ab7 100644 --- a/src/persistence/idpay.ts +++ b/src/persistence/idpay.ts @@ -13,12 +13,13 @@ import { } from "../../generated/definitions/idpay/InitiativeDTO"; import { InstrumentDTO, - StatusEnum as InstrumentStatus + StatusEnum as InstrumentStatus, + InstrumentTypeEnum } from "../../generated/definitions/idpay/InstrumentDTO"; import { InstrumentOperationDTO, OperationTypeEnum as InstrumentOperationTypeEnum, - InstrumentTypeEnum + InstrumentTypeEnum as InstrumentOperationInstrumentTypeEnum } from "../../generated/definitions/idpay/InstrumentOperationDTO"; import { OnboardingOperationDTO, @@ -375,30 +376,30 @@ range(0, walletConfig.refundCount).forEach(() => { generateRandomRejectedInstrumentOperationDTO({ operationType: RejectedInstrumentOperationTypeEnum.REJECTED_DELETE_INSTRUMENT, - instrumentType: InstrumentTypeEnum.CARD + instrumentType: InstrumentOperationInstrumentTypeEnum.CARD }), generateRandomInstrumentOperationDTO({ operationType: InstrumentOperationTypeEnum.DELETE_INSTRUMENT, - instrumentType: InstrumentTypeEnum.CARD + instrumentType: InstrumentOperationInstrumentTypeEnum.CARD }), generateRandomInstrumentOperationDTO({ operationType: InstrumentOperationTypeEnum.DELETE_INSTRUMENT, - instrumentType: InstrumentTypeEnum.CARD, + instrumentType: InstrumentOperationInstrumentTypeEnum.CARD, brand: undefined, maskedPan: undefined }), generateRandomRejectedInstrumentOperationDTO({ operationType: RejectedInstrumentOperationTypeEnum.REJECTED_ADD_INSTRUMENT, - instrumentType: InstrumentTypeEnum.CARD + instrumentType: InstrumentOperationInstrumentTypeEnum.CARD }), generateRandomInstrumentOperationDTO({ operationType: InstrumentOperationTypeEnum.ADD_INSTRUMENT, - instrumentType: InstrumentTypeEnum.CARD + instrumentType: InstrumentOperationInstrumentTypeEnum.CARD }), generateRandomInstrumentOperationDTO({ operationType: InstrumentOperationTypeEnum.ADD_INSTRUMENT, - instrumentType: InstrumentTypeEnum.CARD, + instrumentType: InstrumentOperationInstrumentTypeEnum.CARD, brand: undefined, maskedPan: undefined }), @@ -534,7 +535,7 @@ range(0, walletConfig.discountCount).forEach(() => { instrumentId: ulid(), activationDate: new Date(), status: InstrumentStatus.ACTIVE, - instrumentType: InstrumentTypeEnum.IDPAYCODE + instrumentType: InstrumentTypeEnum.APP_IO_PAYMENT } ] }; diff --git a/src/routers/features/idpay/__tests__/wallet.test.ts b/src/routers/features/idpay/__tests__/wallet.test.ts index 11d7c8ab..f279f2a6 100644 --- a/src/routers/features/idpay/__tests__/wallet.test.ts +++ b/src/routers/features/idpay/__tests__/wallet.test.ts @@ -309,7 +309,7 @@ describe("IDPay Wallet API", () => { describe("PUT enrollInstrumentCode", () => { // eslint-disable-next-line sonarjs/no-duplicate-string it("should return 200", async () => { - const tInitiative = initiatives[0]; + const tInitiative = initiatives[1]; const initiativeId = tInitiative.initiativeId; generateIdPayCode();