From c35b9c34179cb5ee635c2a06f6850823a61eaa5f Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Wed, 24 Jun 2026 13:52:24 -0500 Subject: [PATCH 01/11] fix: update income vouchers field and add enableMultiselectVoucherQuestion feature flag (#6333) Co-authored-by: ludtkemorgan <42942267+ludtkemorgan@users.noreply.github.com> * fix: apply PR review suggestions for incomeVouchers seed data and details display Agent-Logs-Url: https://github.com/bloom-housing/bloom/sessions/fff59308-61f5-44b9-bc07-9195035512cd Co-authored-by: ludtkemorgan <42942267+ludtkemorgan@users.noreply.github.com> * fix: add feature flag to swagger * fix: use none and fix the paper app flow * fix: test fixes * fix: public app improvements * fix: add other languages * fix: paper app flow fix * fix: public cypress test fix * fix: review comments * fix: bug fix * fix: update cypress test * fix: alphabatize enum --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: ludtkemorgan <42942267+ludtkemorgan@users.noreply.github.com> Co-authored-by: Morgan Ludtke --- .../migration.sql | 34 +++ api/prisma/schema.prisma | 4 +- .../seed-helpers/application-factory.ts | 4 +- api/prisma/seed-staging/seed-bridge-bay.ts | 1 + api/src/dtos/applications/application.dto.ts | 5 +- .../enums/feature-flags/feature-flags-enum.ts | 6 + .../services/application-exporter.service.ts | 10 + .../utilities/application-export-helpers.ts | 32 +++ api/test/integration/application.e2e-spec.ts | 14 +- .../integration/permission-tests/helpers.ts | 4 +- .../integration/snapshot-create.e2e-spec.ts | 8 +- .../application-exporter.service.spec.ts | 10 +- .../unit/services/application.service.spec.ts | 6 +- .../services/snapshot-create.service.spec.ts | 8 +- docs/feature-flags.md | 1 + .../enableMultiselectVoucherQuestion.md | 13 ++ shared-helpers/__tests__/testHelpers.ts | 2 +- shared-helpers/src/locales/ar.json | 5 + shared-helpers/src/locales/bn.json | 5 + shared-helpers/src/locales/es.json | 5 + shared-helpers/src/locales/fa.json | 5 + shared-helpers/src/locales/general.json | 5 + shared-helpers/src/locales/hy.json | 5 + shared-helpers/src/locales/ko.json | 5 + shared-helpers/src/locales/tl.json | 5 + shared-helpers/src/locales/vi.json | 5 + shared-helpers/src/locales/zh.json | 5 + shared-helpers/src/types/backend-swagger.ts | 9 +- .../src/utilities/blankApplication.ts | 2 +- .../sections/FormHouseholdIncome.test.tsx | 2 +- .../listings/ListingFormActions.test.tsx | 2 +- .../listings/applications/index.test.tsx | 3 +- .../e2e/default/05-paperApplication.spec.ts | 1 - .../fixtures/alternateContactOnlyData.json | 1 + .../cypress/fixtures/applicantOnlyData.json | 1 + .../cypress/fixtures/application.json | 1 + .../fixtures/demographicsOnlyData.json | 1 + .../cypress/fixtures/emptyApplication.json | 1 + .../fixtures/householdDetailsOnlyData.json | 1 + .../fixtures/householdIncomeOnlyData.json | 1 + .../fixtures/householdMemberOnlyData.json | 1 + .../cypress/fixtures/partialApplicationA.json | 1 + sites/partners/cypress/support/commands.js | 10 +- .../applications/ApplicationsColDefs.tsx | 4 +- .../sections/DetailsHouseholdIncome.tsx | 37 +++- .../PaperApplicationForm.tsx | 11 +- .../sections/FormHouseholdIncome.tsx | 98 +++++++-- .../src/lib/applications/FormTypes.ts | 3 +- .../lib/applications/formatApplicationData.ts | 13 +- .../src/pages/application/[id]/index.tsx | 9 +- .../applications/financial/income.test.tsx | 2 +- .../cypress/mockData/applicationData.ts | 3 +- sites/public/cypress/support/commands.js | 2 +- .../applications/SubmittedApplicationView.tsx | 3 + .../components/shared/FormSummaryDetails.tsx | 12 +- .../pages/applications/financial/income.tsx | 2 +- .../pages/applications/financial/vouchers.tsx | 204 +++++++++++++----- .../src/pages/applications/review/summary.tsx | 4 + .../src/pages/applications/start/autofill.tsx | 4 + 59 files changed, 532 insertions(+), 129 deletions(-) create mode 100644 api/prisma/migrations/62_income_vouchers_to_string_array/migration.sql create mode 100644 docs/feature-flags/enableMultiselectVoucherQuestion.md diff --git a/api/prisma/migrations/62_income_vouchers_to_string_array/migration.sql b/api/prisma/migrations/62_income_vouchers_to_string_array/migration.sql new file mode 100644 index 00000000000..72f804f8a1a --- /dev/null +++ b/api/prisma/migrations/62_income_vouchers_to_string_array/migration.sql @@ -0,0 +1,34 @@ +-- AlterTable: change income_vouchers from boolean to text array + +ALTER TABLE "applications" +ADD COLUMN "income_vouchers_new" TEXT[] NOT NULL DEFAULT '{}'; + +-- Migrate existing true values to ['incomeVoucher'], false/null to ['none'] +UPDATE "applications" +SET "income_vouchers_new" = ARRAY['incomeVoucher'] +WHERE "income_vouchers" = true; + +UPDATE "applications" +SET "income_vouchers_new" = ARRAY['none'] +WHERE "income_vouchers" = false; + +ALTER TABLE "applications" +DROP COLUMN "income_vouchers"; + +ALTER TABLE "applications" +RENAME COLUMN "income_vouchers_new" TO "income_vouchers"; + +-- AlterTable: change income_vouchers from boolean to text array on snapshot table +ALTER TABLE "application_snapshot" +ADD COLUMN "income_vouchers_new" TEXT[] NOT NULL DEFAULT '{}'; + +-- Migrate existing true values to ['incomeVoucher'], false/null to empty array +UPDATE "application_snapshot" +SET "income_vouchers_new" = ARRAY['incomeVoucher'] +WHERE "income_vouchers" = true; + +ALTER TABLE "application_snapshot" +DROP COLUMN "income_vouchers"; + +ALTER TABLE "application_snapshot" +RENAME COLUMN "income_vouchers_new" TO "income_vouchers"; diff --git a/api/prisma/schema.prisma b/api/prisma/schema.prisma index 62dc4ab1f43..2b147b50807 100644 --- a/api/prisma/schema.prisma +++ b/api/prisma/schema.prisma @@ -402,7 +402,7 @@ model Applications { housingStatus String? @map("housing_status") income String? incomePeriod IncomePeriodEnum? @map("income_period") - incomeVouchers Boolean? @map("income_vouchers") + incomeVouchers String[] @map("income_vouchers") // This application is the most recent for the user isNewest Boolean? @default(false) @map("is_newest") language LanguagesEnum? @@ -481,7 +481,7 @@ model ApplicationSnapshot { housingStatus String? @map("housing_status") income String? incomePeriod IncomePeriodEnum? @map("income_period") - incomeVouchers Boolean? @map("income_vouchers") + incomeVouchers String[] @map("income_vouchers") // This application is the most recent for the user isNewest Boolean? @default(false) @map("is_newest") language LanguagesEnum? diff --git a/api/prisma/seed-helpers/application-factory.ts b/api/prisma/seed-helpers/application-factory.ts index 9ef27c4ac84..3baed72c737 100644 --- a/api/prisma/seed-helpers/application-factory.ts +++ b/api/prisma/seed-helpers/application-factory.ts @@ -78,7 +78,7 @@ export const applicationFactory = async (optionalParams?: { ? createdAtDate : dayjs(createdAtDate).add(2, 'days').toDate(), householdSize: householdSize, - income: '40000', + income: randomInt(500, 100000).toString(), incomePeriod: randomBoolean() ? IncomePeriodEnum.perYear : IncomePeriodEnum.perMonth, @@ -132,7 +132,7 @@ export const applicationFactory = async (optionalParams?: { }, } : undefined, - incomeVouchers: randomBoolean(), + incomeVouchers: randomBoolean() ? ['incomeVoucher'] : [], additionalPhoneNumber: includeAdditionalPhone ? optionalParams?.additionalPhone || '(456) 456-4564' : undefined, diff --git a/api/prisma/seed-staging/seed-bridge-bay.ts b/api/prisma/seed-staging/seed-bridge-bay.ts index bf9433999d9..f7b9ac77e30 100644 --- a/api/prisma/seed-staging/seed-bridge-bay.ts +++ b/api/prisma/seed-staging/seed-bridge-bay.ts @@ -2411,6 +2411,7 @@ const featureFlags = [ FeatureFlagEnum.enableListingMap, FeatureFlagEnum.enableListingOpportunity, FeatureFlagEnum.enableListingPagination, + FeatureFlagEnum.enableMultiselectVoucherQuestion, FeatureFlagEnum.enablePartnerDemographics, FeatureFlagEnum.enablePartnerSettings, FeatureFlagEnum.enableReceivedAtAndByFields, diff --git a/api/src/dtos/applications/application.dto.ts b/api/src/dtos/applications/application.dto.ts index 1206741413d..3cb4f408dc2 100644 --- a/api/src/dtos/applications/application.dto.ts +++ b/api/src/dtos/applications/application.dto.ts @@ -114,10 +114,11 @@ export class Application extends AbstractDTO { reasonableAccommodations?: string; @Expose() - @IsBoolean({ groups: [ValidationsGroupsEnum.default] }) + @IsArray({ groups: [ValidationsGroupsEnum.default] }) + @IsString({ each: true, groups: [ValidationsGroupsEnum.default] }) @IsDefined({ groups: [ValidationsGroupsEnum.applicants] }) @ApiPropertyOptional() - incomeVouchers?: boolean; + incomeVouchers?: string[]; @Expose() @IsString({ groups: [ValidationsGroupsEnum.default] }) diff --git a/api/src/enums/feature-flags/feature-flags-enum.ts b/api/src/enums/feature-flags/feature-flags-enum.ts index 112fe2bb46e..5d08cfa568e 100644 --- a/api/src/enums/feature-flags/feature-flags-enum.ts +++ b/api/src/enums/feature-flags/feature-flags-enum.ts @@ -43,6 +43,7 @@ export enum FeatureFlagEnum { enableMarketingFlyer = 'enableMarketingFlyer', enableMarketingStatus = 'enableMarketingStatus', enableMarketingStatusMonths = 'enableMarketingStatusMonths', + enableMultiselectVoucherQuestion = 'enableMultiselectVoucherQuestion', enableNeighborhoodAmenities = 'enableNeighborhoodAmenities', enableNeighborhoodAmenitiesDropdown = 'enableNeighborhoodAmenitiesDropdown', enableNonRegulatedListings = 'enableNonRegulatedListings', @@ -280,6 +281,11 @@ export const featureFlagMap: { description: "When true, the 'marketing status' sub-section uses months instead of seasons (functions only if enableMarketingStatus is also true)", }, + { + name: FeatureFlagEnum.enableMultiselectVoucherQuestion, + description: + 'When true, the vouchers question on the application form becomes a multi-select checkbox experience with Section 8, rental assistance, and none of the above as options', + }, { name: FeatureFlagEnum.enableNeighborhoodAmenities, description: diff --git a/api/src/services/application-exporter.service.ts b/api/src/services/application-exporter.service.ts index 67e84d57489..61644cb1e73 100644 --- a/api/src/services/application-exporter.service.ts +++ b/api/src/services/application-exporter.service.ts @@ -245,6 +245,10 @@ export class ApplicationExporterService { jurisdiction as Jurisdiction, FeatureFlagEnum.swapCommunityTypeWithPrograms, ); + const enableMultiselectVoucherQuestion = doJurisdictionHaveFeatureFlagSet( + jurisdiction as Jurisdiction, + FeatureFlagEnum.enableMultiselectVoucherQuestion, + ); // get all multiselect questions for a listing to build csv headers const multiSelectQuestions = @@ -267,6 +271,7 @@ export class ApplicationExporterService { enableApplicationStatus, enableFullTimeStudentQuestion, enableReasonableAccommodations, + enableMultiselectVoucherQuestion, enableSpokenLanguage, enableGenderQuestion, enableSexualOrientationQuestion, @@ -538,6 +543,10 @@ export class ApplicationExporterService { jurisdiction as Jurisdiction, FeatureFlagEnum.swapCommunityTypeWithPrograms, ); + const enableMultiselectVoucherQuestion = doJurisdictionHaveFeatureFlagSet( + jurisdiction as Jurisdiction, + FeatureFlagEnum.enableMultiselectVoucherQuestion, + ); // get all multiselect questions for a listing to build csv headers const multiSelectQuestions = @@ -560,6 +569,7 @@ export class ApplicationExporterService { enableApplicationStatus, enableFullTimeStudentQuestion, enableReasonableAccommodations, + enableMultiselectVoucherQuestion, enableGenderQuestion, enableSexualOrientationQuestion, enableV2MSQ, diff --git a/api/src/utilities/application-export-helpers.ts b/api/src/utilities/application-export-helpers.ts index 678389108ae..0480a0ad6ce 100644 --- a/api/src/utilities/application-export-helpers.ts +++ b/api/src/utilities/application-export-helpers.ts @@ -34,6 +34,7 @@ export const getExportHeaders = ( enableApplicationStatus?: boolean; enableFullTimeStudentQuestion?: boolean; enableReasonableAccommodations?: boolean; + enableMultiselectVoucherQuestion?: boolean; enableSpokenLanguage?: boolean; enableGenderQuestion?: boolean; enableSexualOrientationQuestion?: boolean; @@ -51,6 +52,7 @@ export const getExportHeaders = ( enableApplicationStatus, enableFullTimeStudentQuestion, enableReasonableAccommodations, + enableMultiselectVoucherQuestion, enableSpokenLanguage, enableGenderQuestion, enableSexualOrientationQuestion, @@ -416,6 +418,18 @@ export const getExportHeaders = ( { path: 'incomeVouchers', label: 'Vouchers or Subsidies', + format: (val: string[]): string => { + if (!enableMultiselectVoucherQuestion) { + return (!val && val.length === 0) || val[0] === 'none' + ? 'No' + : 'Yes'; + } + if (!val || val.length === 0) { + return 'None'; + } + + return val.map((v) => incomeVouchersToReadable(v)).join(', '); + }, }, { path: 'preferredUnitTypes', @@ -1086,3 +1100,21 @@ export const typeMap = { export const unitTypeToReadable = (type: string): string => { return typeMap[type] ?? type; }; + +/** + * @param type value of the income voucher type to convert to readable string + * @returns the string representation of that income voucher type + */ +export const incomeVouchersToReadable = (type: string): string => { + switch (type) { + case 'issuedVouchers': + return 'Section 8'; + case 'rentalAssistance': + return 'Rental Assistance from other source'; + case 'incomeVoucher': + return 'Income Voucher'; + case 'none': + default: + return 'None'; + } +}; diff --git a/api/test/integration/application.e2e-spec.ts b/api/test/integration/application.e2e-spec.ts index 5a2e7cf74db..8ac17beab26 100644 --- a/api/test/integration/application.e2e-spec.ts +++ b/api/test/integration/application.e2e-spec.ts @@ -120,7 +120,7 @@ describe('Application Controller Tests', () => { housingStatus: 'example status', householdExpectingChanges: false, householdStudent: false, - incomeVouchers: false, + incomeVouchers: [], income: '36000', incomePeriod: IncomePeriodEnum.perYear, language: LanguagesEnum.en, @@ -1649,7 +1649,7 @@ describe('Application Controller Tests', () => { sendMailToMailingAddress: true, householdExpectingChanges: false, householdStudent: false, - incomeVouchers: false, + incomeVouchers: [], income: '36000', incomePeriod: IncomePeriodEnum.perYear, language: LanguagesEnum.en, @@ -1848,7 +1848,7 @@ describe('Application Controller Tests', () => { householdSize: 2, householdStudent: false, housingStatus: 'example status', - incomeVouchers: false, + incomeVouchers: [], income: '36000', incomePeriod: IncomePeriodEnum.perYear, language: LanguagesEnum.en, @@ -2022,7 +2022,7 @@ describe('Application Controller Tests', () => { householdSize: 2, householdStudent: false, housingStatus: 'example status', - incomeVouchers: false, + incomeVouchers: [], income: '36000', incomePeriod: IncomePeriodEnum.perYear, language: LanguagesEnum.en, @@ -2183,7 +2183,7 @@ describe('Application Controller Tests', () => { householdSize: 2, householdStudent: false, housingStatus: 'example status', - incomeVouchers: false, + incomeVouchers: [], income: '36000', incomePeriod: IncomePeriodEnum.perYear, language: LanguagesEnum.en, @@ -2345,7 +2345,7 @@ describe('Application Controller Tests', () => { sendMailToMailingAddress: true, householdExpectingChanges: false, householdStudent: false, - incomeVouchers: false, + incomeVouchers: [], income: '36000', incomePeriod: IncomePeriodEnum.perYear, language: LanguagesEnum.en, @@ -2563,7 +2563,7 @@ describe('Application Controller Tests', () => { sendMailToMailingAddress: true, householdExpectingChanges: false, householdStudent: false, - incomeVouchers: false, + incomeVouchers: [], income: '36000', incomePeriod: IncomePeriodEnum.perYear, language: LanguagesEnum.en, diff --git a/api/test/integration/permission-tests/helpers.ts b/api/test/integration/permission-tests/helpers.ts index 5985cfff6a8..db5fec02bd4 100644 --- a/api/test/integration/permission-tests/helpers.ts +++ b/api/test/integration/permission-tests/helpers.ts @@ -400,7 +400,7 @@ export const buildApplicationCreateMock = ( sendMailToMailingAddress: true, householdExpectingChanges: false, householdStudent: false, - incomeVouchers: false, + incomeVouchers: [], income: '36000', incomePeriod: IncomePeriodEnum.perYear, language: LanguagesEnum.en, @@ -499,7 +499,7 @@ export const buildApplicationUpdateMock = ( sendMailToMailingAddress: true, householdExpectingChanges: false, householdStudent: false, - incomeVouchers: false, + incomeVouchers: [], income: '36000', incomePeriod: IncomePeriodEnum.perYear, language: LanguagesEnum.en, diff --git a/api/test/integration/snapshot-create.e2e-spec.ts b/api/test/integration/snapshot-create.e2e-spec.ts index fd56e110617..03aabb4f550 100644 --- a/api/test/integration/snapshot-create.e2e-spec.ts +++ b/api/test/integration/snapshot-create.e2e-spec.ts @@ -1646,7 +1646,7 @@ describe('Snapshot Create Controller Tests', () => { housingStatus: 'example housingStatus', income: 'example income', incomePeriod: IncomePeriodEnum.perMonth, - incomeVouchers: true, + incomeVouchers: ['incomeVoucher'], isNewest: true, language: LanguagesEnum.bn, manualLotteryPositionNumber: 34, @@ -1709,7 +1709,7 @@ describe('Snapshot Create Controller Tests', () => { housingStatus: 'example housingStatus', income: 'example income', incomePeriod: IncomePeriodEnum.perMonth, - incomeVouchers: true, + incomeVouchers: ['incomeVoucher'], isNewest: true, language: LanguagesEnum.bn, manualLotteryPositionNumber: 34, @@ -1902,7 +1902,7 @@ describe('Snapshot Create Controller Tests', () => { housingStatus: 'example housingStatus', income: 'example income', incomePeriod: IncomePeriodEnum.perMonth, - incomeVouchers: true, + incomeVouchers: ['incomeVoucher'], isNewest: true, language: LanguagesEnum.bn, manualLotteryPositionNumber: 34, @@ -2257,7 +2257,7 @@ describe('Snapshot Create Controller Tests', () => { housingStatus: 'example housingStatus', income: 'example income', incomePeriod: IncomePeriodEnum.perMonth, - incomeVouchers: true, + incomeVouchers: ['incomeVoucher'], isNewest: true, language: LanguagesEnum.bn, manualLotteryPositionNumber: 34, diff --git a/api/test/unit/services/application-exporter.service.spec.ts b/api/test/unit/services/application-exporter.service.spec.ts index df138db7f07..898f8181c88 100644 --- a/api/test/unit/services/application-exporter.service.spec.ts +++ b/api/test/unit/services/application-exporter.service.spec.ts @@ -127,7 +127,7 @@ describe('Testing application export service', () => { const headerRow = '"Application Id","Application Confirmation Code","Application Type","Application Submission Date","Primary Applicant First Name","Primary Applicant Middle Name","Primary Applicant Last Name","Primary Applicant Birth Day","Primary Applicant Birth Month","Primary Applicant Birth Year","Primary Applicant Email Address","Primary Applicant Phone Number","Primary Applicant Phone Type","Primary Applicant Additional Phone Number","Primary Applicant Preferred Contact Type","Primary Applicant Work in Region","Primary Applicant Street","Primary Applicant Street 2","Primary Applicant City","Primary Applicant State","Primary Applicant Zip Code","Primary Applicant Mailing Street","Primary Applicant Mailing Street 2","Primary Applicant Mailing City","Primary Applicant Mailing State","Primary Applicant Mailing Zip Code","Primary Applicant Work Street","Primary Applicant Work Street 2","Primary Applicant Work City","Primary Applicant Work State","Primary Applicant Work Zip Code","Alternate Contact First Name","Alternate Contact Last Name","Alternate Contact Type","Alternate Contact Agency","Alternate Contact Other Type","Alternate Contact Email Address","Alternate Contact Phone Number","Alternate Contact Street","Alternate Contact Street 2","Alternate Contact City","Alternate Contact State","Alternate Contact Zip Code","Income","Income Period","Accessibility Mobility","Accessibility Vision","Accessibility Hearing","Accessibility Hearing and Vision","Accessibility Other","Expecting Household Changes","Household Includes Student or Member Nearing 18","Reasonable Accommodations","Vouchers or Subsidies","Requested Unit Types","Preference text 0","Preference text 0 - text - Address","Program text 1","Household Size","Household Member (1) First Name","Household Member (1) Middle Name","Household Member (1) Last Name","Household Member (1) Birth Day","Household Member (1) Birth Month","Household Member (1) Birth Year","Household Member (1) Relationship","Household Member (1) Same as Primary Applicant","Household Member (1) Work in Region","Household Member (1) Street","Household Member (1) Street 2","Household Member (1) City","Household Member (1) State","Household Member (1) Zip Code","Marked As Duplicate","Flagged As Duplicate"'; const firstApp = - '"application 0 firstName","application 0 middleName","application 0 lastName","application 0 birthDay","application 0 birthMonth","application 0 birthYear","application 0 emailaddress","application 0 phoneNumber","application 0 phoneNumberType","additionalPhoneNumber 0",,"yes","application 0 applicantAddress street","application 0 applicantAddress street2","application 0 applicantAddress city","application 0 applicantAddress state","application 0 applicantAddress zipCode","application 0 mailingAddress street","application 0 mailingAddress street2","application 0 mailingAddress city","application 0 mailingAddress state","application 0 mailingAddress zipCode","application 0 applicantWorkAddress street","application 0 applicantWorkAddress street2","application 0 applicantWorkAddress city","application 0 applicantWorkAddress state","application 0 applicantWorkAddress zipCode","application 0 alternateContact firstName","application 0 alternateContact lastName","application 0 alternateContact type","application 0 alternateContact agency","application 0 alternateContact otherType","application 0 alternatecontact emailaddress","application 0 alternateContact phoneNumber","application 0 alternateContact address street","application 0 alternateContact address street2","application 0 alternateContact address city","application 0 alternateContact address state","application 0 alternateContact address zipCode","income 0","per month",,,,,,"true","true",,"true","Studio,One Bedroom",,,,,,,,,,,,,,,,,,,,'; + '"application 0 firstName","application 0 middleName","application 0 lastName","application 0 birthDay","application 0 birthMonth","application 0 birthYear","application 0 emailaddress","application 0 phoneNumber","application 0 phoneNumberType","additionalPhoneNumber 0",,"yes","application 0 applicantAddress street","application 0 applicantAddress street2","application 0 applicantAddress city","application 0 applicantAddress state","application 0 applicantAddress zipCode","application 0 mailingAddress street","application 0 mailingAddress street2","application 0 mailingAddress city","application 0 mailingAddress state","application 0 mailingAddress zipCode","application 0 applicantWorkAddress street","application 0 applicantWorkAddress street2","application 0 applicantWorkAddress city","application 0 applicantWorkAddress state","application 0 applicantWorkAddress zipCode","application 0 alternateContact firstName","application 0 alternateContact lastName","application 0 alternateContact type","application 0 alternateContact agency","application 0 alternateContact otherType","application 0 alternatecontact emailaddress","application 0 alternateContact phoneNumber","application 0 alternateContact address street","application 0 alternateContact address street2","application 0 alternateContact address city","application 0 alternateContact address state","application 0 alternateContact address zipCode","income 0","per month",,,,,,"true","true",,"Yes","Studio,One Bedroom",,,,,,,,,,,,,,,,,,,,'; const mockedStream = new PassThrough(); exportResponse.pipe(mockedStream); @@ -191,7 +191,7 @@ describe('Testing application export service', () => { const headerRow = '"Application Id","Application Confirmation Code","Application Type","Application Submission Date","Primary Applicant First Name","Primary Applicant Middle Name","Primary Applicant Last Name","Primary Applicant Birth Day","Primary Applicant Birth Month","Primary Applicant Birth Year","Primary Applicant Email Address","Primary Applicant Phone Number","Primary Applicant Phone Type","Primary Applicant Additional Phone Number","Primary Applicant Preferred Contact Type","Primary Applicant Work in Region","Primary Applicant Street","Primary Applicant Street 2","Primary Applicant City","Primary Applicant State","Primary Applicant Zip Code","Primary Applicant Mailing Street","Primary Applicant Mailing Street 2","Primary Applicant Mailing City","Primary Applicant Mailing State","Primary Applicant Mailing Zip Code","Primary Applicant Work Street","Primary Applicant Work Street 2","Primary Applicant Work City","Primary Applicant Work State","Primary Applicant Work Zip Code","Alternate Contact First Name","Alternate Contact Last Name","Alternate Contact Type","Alternate Contact Agency","Alternate Contact Other Type","Alternate Contact Email Address","Alternate Contact Phone Number","Alternate Contact Street","Alternate Contact Street 2","Alternate Contact City","Alternate Contact State","Alternate Contact Zip Code","Income","Income Period","Accessibility Mobility","Accessibility Vision","Accessibility Hearing","Accessibility Hearing and Vision","Accessibility Other","Expecting Household Changes","Household Includes Student or Member Nearing 18","Reasonable Accommodations","Vouchers or Subsidies","Requested Unit Types","Preference text 0","Program text 1","Household Size","Marked As Duplicate","Flagged As Duplicate","Ethnicity","Race","How did you Hear?"'; const firstApp = - '"application 0 firstName","application 0 middleName","application 0 lastName","application 0 birthDay","application 0 birthMonth","application 0 birthYear","application 0 emailaddress","application 0 phoneNumber","application 0 phoneNumberType","additionalPhoneNumber 0",,"yes","application 0 applicantAddress street","application 0 applicantAddress street2","application 0 applicantAddress city","application 0 applicantAddress state","application 0 applicantAddress zipCode","application 0 mailingAddress street","application 0 mailingAddress street2","application 0 mailingAddress city","application 0 mailingAddress state","application 0 mailingAddress zipCode","application 0 applicantWorkAddress street","application 0 applicantWorkAddress street2","application 0 applicantWorkAddress city","application 0 applicantWorkAddress state","application 0 applicantWorkAddress zipCode","application 0 alternateContact firstName","application 0 alternateContact lastName","application 0 alternateContact type","application 0 alternateContact agency","application 0 alternateContact otherType","application 0 alternatecontact emailaddress","application 0 alternateContact phoneNumber","application 0 alternateContact address street","application 0 alternateContact address street2","application 0 alternateContact address city","application 0 alternateContact address state","application 0 alternateContact address zipCode","income 0","per month",,,,,,"true","true",,"true","Studio,One Bedroom",,,,,,,"Decline to Respond"'; + '"application 0 firstName","application 0 middleName","application 0 lastName","application 0 birthDay","application 0 birthMonth","application 0 birthYear","application 0 emailaddress","application 0 phoneNumber","application 0 phoneNumberType","additionalPhoneNumber 0",,"yes","application 0 applicantAddress street","application 0 applicantAddress street2","application 0 applicantAddress city","application 0 applicantAddress state","application 0 applicantAddress zipCode","application 0 mailingAddress street","application 0 mailingAddress street2","application 0 mailingAddress city","application 0 mailingAddress state","application 0 mailingAddress zipCode","application 0 applicantWorkAddress street","application 0 applicantWorkAddress street2","application 0 applicantWorkAddress city","application 0 applicantWorkAddress state","application 0 applicantWorkAddress zipCode","application 0 alternateContact firstName","application 0 alternateContact lastName","application 0 alternateContact type","application 0 alternateContact agency","application 0 alternateContact otherType","application 0 alternatecontact emailaddress","application 0 alternateContact phoneNumber","application 0 alternateContact address street","application 0 alternateContact address street2","application 0 alternateContact address city","application 0 alternateContact address state","application 0 alternateContact address zipCode","income 0","per month",,,,,,"true","true",,"Yes","Studio,One Bedroom",,,,,,,"Decline to Respond"'; const mockedStream = new PassThrough(); exportResponse.pipe(mockedStream); @@ -254,7 +254,7 @@ describe('Testing application export service', () => { const headerRow = '"Application Id","Application Confirmation Code","Application Type","Application Submission Date","Primary Applicant First Name","Primary Applicant Middle Name","Primary Applicant Last Name","Primary Applicant Birth Day","Primary Applicant Birth Month","Primary Applicant Birth Year","Primary Applicant Email Address","Primary Applicant Phone Number","Primary Applicant Phone Type","Primary Applicant Additional Phone Number","Primary Applicant Preferred Contact Type","Primary Applicant Work in Region","Primary Applicant Street","Primary Applicant Street 2","Primary Applicant City","Primary Applicant State","Primary Applicant Zip Code","Primary Applicant Mailing Street","Primary Applicant Mailing Street 2","Primary Applicant Mailing City","Primary Applicant Mailing State","Primary Applicant Mailing Zip Code","Primary Applicant Work Street","Primary Applicant Work Street 2","Primary Applicant Work City","Primary Applicant Work State","Primary Applicant Work Zip Code","Alternate Contact First Name","Alternate Contact Last Name","Alternate Contact Type","Alternate Contact Agency","Alternate Contact Other Type","Alternate Contact Email Address","Alternate Contact Phone Number","Alternate Contact Street","Alternate Contact Street 2","Alternate Contact City","Alternate Contact State","Alternate Contact Zip Code","Income","Income Period","Accessibility Mobility","Accessibility Vision","Accessibility Hearing","Accessibility Hearing and Vision","Accessibility Other","Expecting Household Changes","Household Includes Student or Member Nearing 18","Vouchers or Subsidies","Requested Unit Types","Preference text 0","Preference text 0 - text - Address","Program text 1","Household Size","Household Member (1) First Name","Household Member (1) Middle Name","Household Member (1) Last Name","Household Member (1) Birth Day","Household Member (1) Birth Month","Household Member (1) Birth Year","Household Member (1) Relationship","Household Member (1) Same as Primary Applicant","Household Member (1) Work in Region","Household Member (1) Street","Household Member (1) Street 2","Household Member (1) City","Household Member (1) State","Household Member (1) Zip Code","Marked As Duplicate","Flagged As Duplicate"'; const firstApp = - '"application 0 firstName","application 0 middleName","application 0 lastName","application 0 birthDay","application 0 birthMonth","application 0 birthYear","application 0 emailaddress","application 0 phoneNumber","application 0 phoneNumberType","additionalPhoneNumber 0",,"yes","application 0 applicantAddress street","application 0 applicantAddress street2","application 0 applicantAddress city","application 0 applicantAddress state","application 0 applicantAddress zipCode","application 0 mailingAddress street","application 0 mailingAddress street2","application 0 mailingAddress city","application 0 mailingAddress state","application 0 mailingAddress zipCode","application 0 applicantWorkAddress street","application 0 applicantWorkAddress street2","application 0 applicantWorkAddress city","application 0 applicantWorkAddress state","application 0 applicantWorkAddress zipCode","application 0 alternateContact firstName","application 0 alternateContact lastName","application 0 alternateContact type","application 0 alternateContact agency","application 0 alternateContact otherType","application 0 alternatecontact emailaddress","application 0 alternateContact phoneNumber","application 0 alternateContact address street","application 0 alternateContact address street2","application 0 alternateContact address city","application 0 alternateContact address state","application 0 alternateContact address zipCode","income 0","per month",,,,,,"true","true","true","Studio,One Bedroom",,,,,,,,,,,,,,,,,,,,'; + '"application 0 firstName","application 0 middleName","application 0 lastName","application 0 birthDay","application 0 birthMonth","application 0 birthYear","application 0 emailaddress","application 0 phoneNumber","application 0 phoneNumberType","additionalPhoneNumber 0",,"yes","application 0 applicantAddress street","application 0 applicantAddress street2","application 0 applicantAddress city","application 0 applicantAddress state","application 0 applicantAddress zipCode","application 0 mailingAddress street","application 0 mailingAddress street2","application 0 mailingAddress city","application 0 mailingAddress state","application 0 mailingAddress zipCode","application 0 applicantWorkAddress street","application 0 applicantWorkAddress street2","application 0 applicantWorkAddress city","application 0 applicantWorkAddress state","application 0 applicantWorkAddress zipCode","application 0 alternateContact firstName","application 0 alternateContact lastName","application 0 alternateContact type","application 0 alternateContact agency","application 0 alternateContact otherType","application 0 alternatecontact emailaddress","application 0 alternateContact phoneNumber","application 0 alternateContact address street","application 0 alternateContact address street2","application 0 alternateContact address city","application 0 alternateContact address state","application 0 alternateContact address zipCode","income 0","per month",,,,,,"true","true","Yes","Studio,One Bedroom",,,,,,,,,,,,,,,,,,,,'; const mockedStream = new PassThrough(); exportResponse.pipe(mockedStream); @@ -565,7 +565,7 @@ describe('Testing application export service', () => { expect(objectData).toBe(undefined); expect(stringData).toEqual( - `"${id.toString()}","confirmationCode 1","electronic","12-05-2024 03:24:00AM PST","application 1 firstName","application 1 middleName","application 1 lastName","application 1 birthDay","application 1 birthMonth","application 1 birthYear","application 1 emailaddress","application 1 phoneNumber","application 1 phoneNumberType","additionalPhoneNumber 1",,"yes","application 1 applicantAddress street","application 1 applicantAddress street2","application 1 applicantAddress city","application 1 applicantAddress state","application 1 applicantAddress zipCode","application 1 mailingAddress street","application 1 mailingAddress street2","application 1 mailingAddress city","application 1 mailingAddress state","application 1 mailingAddress zipCode","application 1 applicantWorkAddress street","application 1 applicantWorkAddress street2","application 1 applicantWorkAddress city","application 1 applicantWorkAddress state","application 1 applicantWorkAddress zipCode","application 1 alternateContact firstName","application 1 alternateContact lastName","application 1 alternateContact type","application 1 alternateContact agency","application 1 alternateContact otherType","application 1 alternatecontact emailaddress","application 1 alternateContact phoneNumber","application 1 alternateContact address street","application 1 alternateContact address street2","application 1 alternateContact address city","application 1 alternateContact address state","application 1 alternateContact address zipCode","income 1","per month",,,,,,"true","true",,"true","Studio,One Bedroom","1","true","true"`, + `"${id.toString()}","confirmationCode 1","electronic","12-05-2024 03:24:00AM PST","application 1 firstName","application 1 middleName","application 1 lastName","application 1 birthDay","application 1 birthMonth","application 1 birthYear","application 1 emailaddress","application 1 phoneNumber","application 1 phoneNumberType","additionalPhoneNumber 1",,"yes","application 1 applicantAddress street","application 1 applicantAddress street2","application 1 applicantAddress city","application 1 applicantAddress state","application 1 applicantAddress zipCode","application 1 mailingAddress street","application 1 mailingAddress street2","application 1 mailingAddress city","application 1 mailingAddress state","application 1 mailingAddress zipCode","application 1 applicantWorkAddress street","application 1 applicantWorkAddress street2","application 1 applicantWorkAddress city","application 1 applicantWorkAddress state","application 1 applicantWorkAddress zipCode","application 1 alternateContact firstName","application 1 alternateContact lastName","application 1 alternateContact type","application 1 alternateContact agency","application 1 alternateContact otherType","application 1 alternatecontact emailaddress","application 1 alternateContact phoneNumber","application 1 alternateContact address street","application 1 alternateContact address street2","application 1 alternateContact address city","application 1 alternateContact address state","application 1 alternateContact address zipCode","income 1","per month",,,,,,"true","true",,"Yes","Studio,One Bedroom","1","true","true"`, ); }); @@ -662,7 +662,7 @@ describe('Testing application export service', () => { id: id, income: 'income 1', incomePeriod: 'per month', - incomeVouchers: 'true', + incomeVouchers: 'Yes', markedAsDuplicate: 'true', preferredUnitTypes: 'Studio,One Bedroom', reasonableAccommodations: '', diff --git a/api/test/unit/services/application.service.spec.ts b/api/test/unit/services/application.service.spec.ts index 2326bb418e5..22acc6a70dc 100644 --- a/api/test/unit/services/application.service.spec.ts +++ b/api/test/unit/services/application.service.spec.ts @@ -69,7 +69,7 @@ export const mockApplication = (options: { sendMailToMailingAddress: true, householdExpectingChanges: true, householdStudent: true, - incomeVouchers: true, + incomeVouchers: ['incomeVoucher'], income: `income ${options.position}`, incomePeriod: IncomePeriodEnum.perMonth, preferences: options.preferences || [], @@ -272,7 +272,7 @@ export const mockCreateApplicationData = ( householdSize: 2, householdStudent: false, housingStatus: 'example housing status', - incomeVouchers: false, + incomeVouchers: [], income: '36000', incomePeriod: IncomePeriodEnum.perYear, language: LanguagesEnum.en, @@ -360,7 +360,7 @@ const buildExpectedApplicationData = ({ sendMailToMailingAddress: true, householdExpectingChanges: false, householdStudent: false, - incomeVouchers: false, + incomeVouchers: [], income: '36000', incomePeriod: IncomePeriodEnum.perYear, language: LanguagesEnum.en, diff --git a/api/test/unit/services/snapshot-create.service.spec.ts b/api/test/unit/services/snapshot-create.service.spec.ts index c9c2b67258f..915b44a314b 100644 --- a/api/test/unit/services/snapshot-create.service.spec.ts +++ b/api/test/unit/services/snapshot-create.service.spec.ts @@ -3303,7 +3303,7 @@ describe('Testing snapshot create service', () => { housingStatus: 'example housingStatus', income: 'example income', incomePeriod: IncomePeriodEnum.perMonth, - incomeVouchers: true, + incomeVouchers: ['incomeVoucher'], isNewest: true, language: LanguagesEnum.bn, manualLotteryPositionNumber: 34, @@ -3637,7 +3637,7 @@ describe('Testing snapshot create service', () => { housingStatus: 'example housingStatus', income: 'example income', incomePeriod: IncomePeriodEnum.perMonth, - incomeVouchers: true, + incomeVouchers: ['incomeVoucher'], isNewest: true, language: LanguagesEnum.bn, manualLotteryPositionNumber: 34, @@ -3682,7 +3682,7 @@ describe('Testing snapshot create service', () => { housingStatus: 'example housingStatus', income: 'example income', incomePeriod: IncomePeriodEnum.perMonth, - incomeVouchers: true, + incomeVouchers: ['incomeVoucher'], isNewest: true, language: LanguagesEnum.bn, manualLotteryPositionNumber: 34, @@ -4264,7 +4264,7 @@ describe('Testing snapshot create service', () => { housingStatus: 'example housingStatus', income: 'example income', incomePeriod: IncomePeriodEnum.perMonth, - incomeVouchers: true, + incomeVouchers: ['incomeVoucher'], isNewest: true, language: LanguagesEnum.bn, manualLotteryPositionNumber: 34, diff --git a/docs/feature-flags.md b/docs/feature-flags.md index a2159af8aa3..44cb01dc162 100644 --- a/docs/feature-flags.md +++ b/docs/feature-flags.md @@ -83,6 +83,7 @@ The following are all of the feature flags currently available in the Bloom plat | [enableRegions](./feature-flags/enableRegions.md) | When true, the region can be defined for the building address | | [enableResources](./feature-flags/enableResources.md) | When true, the public site displays links to resources on various pages | | [enableSection8Question](./feature-flags/enableSection8Question.md) | When true, the Section 8 listing data will be visible | +| [enableMultiselectVoucherQuestion](./feature-flags/enableMultiselectVoucherQuestion.md) | When true, the vouchers question on the application form becomes a multi-select checkbox experience with Section 8, rental assistance, and none of the above as options | | [enableSexualOrientationQuestion](./feature-flags/enableSexualOrientationQuestion.md) | When true, the sexual orientation question is displayed in the public and partner application demographics section | | [enableSingleUseCode](./feature-flags/enableSingleUseCode.md) | When true, the backend allows for logging into this jurisdiction using the single use code flow | | [enableSmokingPolicyRadio](./feature-flags/enableSmokingPolicyRadio.md) | When true, the listing 'Smoking policy' field is a radio group | diff --git a/docs/feature-flags/enableMultiselectVoucherQuestion.md b/docs/feature-flags/enableMultiselectVoucherQuestion.md new file mode 100644 index 00000000000..5b3da3643b8 --- /dev/null +++ b/docs/feature-flags/enableMultiselectVoucherQuestion.md @@ -0,0 +1,13 @@ +# enableMultiselectVoucherQuestion + +## Name + +`enableMultiselectVoucherQuestion` + +## Description + +When true, the vouchers question on the application form becomes a multi-select checkbox experience with Section 8, rental assistance, and none of the above as options + +## Additional Information + +## Images diff --git a/shared-helpers/__tests__/testHelpers.ts b/shared-helpers/__tests__/testHelpers.ts index bd544f262ce..76c32f4608e 100644 --- a/shared-helpers/__tests__/testHelpers.ts +++ b/shared-helpers/__tests__/testHelpers.ts @@ -196,7 +196,7 @@ export const application: Application = { householdExpectingChanges: true, householdStudent: false, reasonableAccommodations: "Wheelchair-accessible unit entrance", - incomeVouchers: true, + incomeVouchers: ["incomeVoucher"], income: "40000.00", incomePeriod: IncomePeriodEnum.perYear, status: ApplicationStatusEnum.submitted, diff --git a/shared-helpers/src/locales/ar.json b/shared-helpers/src/locales/ar.json index 43d40ccddc9..a271332cbcb 100644 --- a/shared-helpers/src/locales/ar.json +++ b/shared-helpers/src/locales/ar.json @@ -259,12 +259,17 @@ "application.financial.income.validationError.reason.low": "دخل أسرتك منخفض للغاية.", "application.financial.vouchers.housingVouchers.strong": "قسائم الإسكان", "application.financial.vouchers.housingVouchers.text": "مثل القسم 8", + "application.financial.vouchers.issuedVouchers": "قسيمة اختيار السكن بموجب القسم 8", "application.financial.vouchers.legend": "قسائم الإسكان والدخل غير الخاضع للضريبة أو إعانات الإيجار", + "application.financial.vouchers.none": "لا شيء مما سبق", "application.financial.vouchers.nonTaxableIncome.strong": "الدخل غير الخاضع للضريبة", "application.financial.vouchers.nonTaxableIncome.text": "مثل SSI أو SSDI أو مدفوعات إعالة الطفل أو مزايا تعويض العمال", + "application.financial.vouchers.rentalAssistance": "مساعدة الإيجار من مصادر أخرى", "application.financial.vouchers.rentalSubsidies.strong": "إعانات الإيجار", "application.financial.vouchers.rentalSubsidies.text": "مثل VASH و HSA و HOPWA والجمعيات الخيرية الكاثوليكية ومؤسسة الإيدز ، إلخ.", + "application.financial.vouchers.subtitleAlt": "تشمل المساعدة في الإيجار من مصادر أخرى الدعم المقدم من برامج مثل مؤسسة كاريتاس الكاثوليكية أو مؤسسة الإيدز.", "application.financial.vouchers.title": "هل تتلقى أنت أو أي شخص في هذا التطبيق أيًا مما يلي؟", + "application.financial.vouchers.titleAlt": "هل تتلقى أنت أو أي شخص في منزلك قسائم صادرة عن برنامج الإسكان المدعوم (Section 8) أو هيئة الإسكان، بما في ذلك قسائم الإسكان المدعوم لشؤون المحاربين القدامى (VASH)، أو مساعدات إيجارية من مصادر أخرى؟", "application.form.general.advocateWarning": "أنت تقدم الطلب نيابة عن عميل؛ يرجى إدخال معلومات عميلك، وليس معلوماتك الشخصية.", "application.form.general.saveAndFinishLater": "احفظها وأكملها لاحقًا", "application.form.general.saveAndReturn": "حفظ والعودة للمراجعة", diff --git a/shared-helpers/src/locales/bn.json b/shared-helpers/src/locales/bn.json index ad9b4696e04..07d5bb49c7b 100644 --- a/shared-helpers/src/locales/bn.json +++ b/shared-helpers/src/locales/bn.json @@ -259,12 +259,17 @@ "application.financial.income.validationError.reason.low": "আপনার পরিবারের আয় খুবই কম।", "application.financial.vouchers.housingVouchers.strong": "হাউজিং ভাউচার", "application.financial.vouchers.housingVouchers.text": "অধ্যায় 8 মত", + "application.financial.vouchers.issuedVouchers": "সেকশন ৮ হাউজিং চয়েস ভাউচার", "application.financial.vouchers.legend": "হাউজিং ভাউচার, ননটেক্সেবল আয় বা ভাড়া ভর্তুকি", + "application.financial.vouchers.none": "উপরের কোনোটিই নয়", "application.financial.vouchers.nonTaxableIncome.strong": "অ-করযোগ্য আয়", "application.financial.vouchers.nonTaxableIncome.text": "যেমন SSI, SSDI, চাইল্ড সাপোর্ট পেমেন্ট, অথবা শ্রমিকের ক্ষতিপূরণ সুবিধা", + "application.financial.vouchers.rentalAssistance": "অন্যান্য উৎস থেকে ভাড়া সহায়তা", "application.financial.vouchers.rentalSubsidies.strong": "ভাড়া ভর্তুকি", "application.financial.vouchers.rentalSubsidies.text": "যেমন VASH, HSA, HOPWA, Catholic Charities, AIDS Foundation, ইত্যাদি।", + "application.financial.vouchers.subtitleAlt": "অন্যান্য উৎস থেকে প্রাপ্ত ভাড়া সহায়তার মধ্যে ক্যাথলিক চ্যারিটিজ বা এইডস ফাউন্ডেশনের মতো কর্মসূচি থেকে প্রাপ্ত সহায়তা অন্তর্ভুক্ত।", "application.financial.vouchers.title": "আপনি বা এই অ্যাপ্লিকেশনে কেউ নিচের কোনটি পান?", + "application.financial.vouchers.titleAlt": "আপনি বা আপনার পরিবারের কেউ কি সেকশন ৮ বা হাউজিং অথরিটি কর্তৃক ইস্যুকৃত ভাউচার, যার মধ্যে ভেটেরান্স অ্যাফেয়ার্স সাপোর্টিভ হাউজিং (VASH) ভাউচার অন্তর্ভুক্ত, অথবা অন্য কোনো উৎস থেকে ভাড়া সহায়তা পেয়ে থাকেন?", "application.form.general.advocateWarning": "আপনি একজন ক্লায়েন্টের পক্ষে আবেদন করছেন; অনুগ্রহ করে আপনার ক্লায়েন্টের তথ্য লিখুন, নিজের তথ্য নয়।", "application.form.general.saveAndFinishLater": "সংরক্ষণ করুন এবং পরে শেষ করুন", "application.form.general.saveAndReturn": "সংরক্ষণ করুন এবং পর্যালোচনায় ফিরে আসুন", diff --git a/shared-helpers/src/locales/es.json b/shared-helpers/src/locales/es.json index 7c3021c54ab..239e8c65358 100644 --- a/shared-helpers/src/locales/es.json +++ b/shared-helpers/src/locales/es.json @@ -259,12 +259,17 @@ "application.financial.income.validationError.reason.low": "Los ingresos de su hogar son demasiado bajos.", "application.financial.vouchers.housingVouchers.strong": "Cupones de viviendas", "application.financial.vouchers.housingVouchers.text": "como Section 8", + "application.financial.vouchers.issuedVouchers": "Vale de elección de vivienda de la Sección 8", "application.financial.vouchers.legend": "Recibos de vivienda, ingresos deducibles o subsidios de alquiler", + "application.financial.vouchers.none": "Ninguna de las anteriores", "application.financial.vouchers.nonTaxableIncome.strong": "Ingresos no gravables de impuestos", "application.financial.vouchers.nonTaxableIncome.text": "como SSI, SSDI, pagos de manutención infantil o beneficios de compensaciones del trabajador", + "application.financial.vouchers.rentalAssistance": "Ayuda para el alquiler procedente de otras fuentes", "application.financial.vouchers.rentalSubsidies.strong": "Subsidios en el alquiler", "application.financial.vouchers.rentalSubsidies.text": "como VASH, HSA, HOPWA, Catholic Charities, AIDS Foundation, etc.", + "application.financial.vouchers.subtitleAlt": "La ayuda para el alquiler procedente de otras fuentes incluye el apoyo de programas como Catholic Charities o la Fundación contra el SIDA.", "application.financial.vouchers.title": "¿Recibe usted o alguna otra persona de esta solicitud alguno de los siguientes?", + "application.financial.vouchers.titleAlt": "¿Usted o algún miembro de su hogar recibe vales del Programa de la Sección 8 o vales emitidos por la Autoridad de Vivienda, incluidos los vales de Vivienda de Apoyo para Veteranos (VASH), o asistencia para el alquiler de otras fuentes?", "application.form.general.advocateWarning": "Usted está presentando la solicitud en nombre de un cliente; ingrese la información de su cliente, no la suya propia.", "application.form.general.saveAndFinishLater": "Guardar y terminar más tarde", "application.form.general.saveAndReturn": "Guardar y regresar a revisión", diff --git a/shared-helpers/src/locales/fa.json b/shared-helpers/src/locales/fa.json index 74a1666fea9..0cd5793ab60 100644 --- a/shared-helpers/src/locales/fa.json +++ b/shared-helpers/src/locales/fa.json @@ -259,12 +259,17 @@ "application.financial.income.validationError.reason.low": "درآمد خانوار شما خیلی کم است.", "application.financial.vouchers.housingVouchers.strong": "کوپن‌های مسکن", "application.financial.vouchers.housingVouchers.text": "مثل بخش ۸", + "application.financial.vouchers.issuedVouchers": "کوپن انتخاب مسکن بخش ۸", "application.financial.vouchers.legend": "کوپن‌های مسکن، درآمد معاف از مالیات یا یارانه‌های اجاره", + "application.financial.vouchers.none": "هیچ یک از موارد فوق", "application.financial.vouchers.nonTaxableIncome.strong": "درآمد غیر مشمول مالیات", "application.financial.vouchers.nonTaxableIncome.text": "مانند SSI، SSDI، پرداخت‌های حمایت از کودک یا مزایای جبران خسارت کارگران", + "application.financial.vouchers.rentalAssistance": "کمک هزینه اجاره از منابع دیگر", "application.financial.vouchers.rentalSubsidies.strong": "یارانه اجاره", "application.financial.vouchers.rentalSubsidies.text": "مانند VASH، HSA، HOPWA، خیریه‌های کاتولیک، بنیاد ایدز و غیره.", + "application.financial.vouchers.subtitleAlt": "کمک هزینه اجاره از منابع دیگر شامل حمایت از برنامه‌هایی مانند خیریه‌های کاتولیک یا بنیاد ایدز می‌شود.", "application.financial.vouchers.title": "آیا شما یا هر یک از اعضای این درخواست، موارد زیر را دریافت می‌کنید؟", + "application.financial.vouchers.titleAlt": "آیا شما یا هر یک از اعضای خانواده‌تان کوپن‌های بخش ۸ یا کوپن‌های صادر شده توسط اداره مسکن، از جمله کوپن‌های مسکن حمایتی امور ایثارگران (VASH)، یا کمک هزینه اجاره از منابع دیگر دریافت می‌کنید؟", "application.form.general.advocateWarning": "شما از طرف یک موکل درخواست می‌دهید؛ لطفاً اطلاعات موکل خود را وارد کنید، نه اطلاعات خودتان را .", "application.form.general.saveAndFinishLater": "ذخیره کنید و بعداً تمام کنید", "application.form.general.saveAndReturn": "ذخیره و بازگشت به بررسی", diff --git a/shared-helpers/src/locales/general.json b/shared-helpers/src/locales/general.json index 9d8b93ecee3..42873aeacfb 100644 --- a/shared-helpers/src/locales/general.json +++ b/shared-helpers/src/locales/general.json @@ -259,11 +259,16 @@ "application.financial.income.validationError.reason.low": "Your household income is too low.", "application.financial.vouchers.housingVouchers.strong": "Housing vouchers", "application.financial.vouchers.housingVouchers.text": "like Section 8", + "application.financial.vouchers.issuedVouchers": "Section 8 Housing Choice Voucher", "application.financial.vouchers.legend": "Housing vouchers, nontaxable income or rental subsidies", + "application.financial.vouchers.none": "None of the above", "application.financial.vouchers.nonTaxableIncome.strong": "Non-taxable income", "application.financial.vouchers.nonTaxableIncome.text": "like SSI, SSDI, child support payments, or worker's compensation benefits", + "application.financial.vouchers.rentalAssistance": "Rental assistance from other sources", "application.financial.vouchers.rentalSubsidies.strong": "Rental subsidies", "application.financial.vouchers.rentalSubsidies.text": "like VASH, HSA, HOPWA, Catholic Charities, AIDS Foundation, etc.", + "application.financial.vouchers.subtitleAlt": "Rental assistance from other sources includes support from programs such as Catholic Charities or the AIDS Foundation.", + "application.financial.vouchers.titleAlt": "Do you or anyone in your household receive Section 8 or Housing Authority issued vouchers, including Veterans Affairs Supportive Housing (VASH) vouchers, or rental assistance from other sources?", "application.financial.vouchers.title": "Do you or anyone on this application receive any of the following?", "application.form.general.advocateWarning": "You are applying on behalf of a client; please enter your client’s information, not your own.", "application.form.general.saveAndFinishLater": "Save and finish later", diff --git a/shared-helpers/src/locales/hy.json b/shared-helpers/src/locales/hy.json index e39b7b58b30..a9dc9ea9e94 100644 --- a/shared-helpers/src/locales/hy.json +++ b/shared-helpers/src/locales/hy.json @@ -259,12 +259,17 @@ "application.financial.income.validationError.reason.low": "Ձեր ընտանիքի եկամուտը չափազանց ցածր է։", "application.financial.vouchers.housingVouchers.strong": "Բնակարանային վաուչերներ", "application.financial.vouchers.housingVouchers.text": "ինչպես 8-րդ բաժինը", + "application.financial.vouchers.issuedVouchers": "Բաժին 8՝ Բնակարանային ընտրության վկայական", "application.financial.vouchers.legend": "Բնակարանային վաուչերներ, չհարկվող եկամուտ կամ վարձակալության սուբսիդիաներ", + "application.financial.vouchers.none": "Վերը նշվածներից ոչ մեկը", "application.financial.vouchers.nonTaxableIncome.strong": "Ոչ հարկվող եկամուտ", "application.financial.vouchers.nonTaxableIncome.text": "ինչպիսիք են՝ SSI-ը, SSDI-ը, երեխայի խնամքի վճարումները կամ աշխատողի փոխհատուցման նպաստները", + "application.financial.vouchers.rentalAssistance": "Վարձակալության օգնություն այլ աղբյուրներից", "application.financial.vouchers.rentalSubsidies.strong": "Վարձավճարի սուբսիդիաներ", "application.financial.vouchers.rentalSubsidies.text": "ինչպիսիք են VASH-ը, HSA-ն, HOPWA-ն, կաթոլիկ բարեգործական կազմակերպությունները, AIDS-ի հիմնադրամը և այլն:", + "application.financial.vouchers.subtitleAlt": "Այլ աղբյուրներից վարձակալության օգնությունը ներառում է այնպիսի ծրագրերի աջակցություն, ինչպիսիք են Կաթոլիկ բարեգործությունները կամ ՁԻԱՀ-ի հիմնադրամը:", "application.financial.vouchers.title": "Դուք կամ այս դիմումում նշված որևէ մեկը ստանո՞ւմ եք հետևյալներից որևէ մեկը։", + "application.financial.vouchers.titleAlt": "Դուք կամ ձեր տնային տնտեսության որևէ անդամ ստանո՞ւմ եք 8-րդ բաժնի կամ Բնակարանային վարչության կողմից տրամադրված վաուչերներ, այդ թվում՝ Վետերանների հարցերով աջակցող բնակարանային (VASH) վաուչերներ, կամ վարձակալության օգնություն այլ աղբյուրներից:", "application.form.general.advocateWarning": "Դուք դիմում եք հաճախորդի անունից։ Խնդրում ենք մուտքագրել ձեր հաճախորդի տվյալները, այլ ոչ թե ձեր սեփականը ։", "application.form.general.saveAndFinishLater": "Պահպանել և ավարտել ավելի ուշ", "application.form.general.saveAndReturn": "Պահպանել և վերադառնալ ակնարկին", diff --git a/shared-helpers/src/locales/ko.json b/shared-helpers/src/locales/ko.json index f021f9007e7..1874f4e4618 100644 --- a/shared-helpers/src/locales/ko.json +++ b/shared-helpers/src/locales/ko.json @@ -259,12 +259,17 @@ "application.financial.income.validationError.reason.low": "귀하의 가구 소득이 너무 낮습니다.", "application.financial.vouchers.housingVouchers.strong": "주택 바우처", "application.financial.vouchers.housingVouchers.text": "섹션 8처럼", + "application.financial.vouchers.issuedVouchers": "섹션 8 주택 선택 바우처", "application.financial.vouchers.legend": "주택 바우처, 비과세 소득 또는 임대료 보조금", + "application.financial.vouchers.none": "위의 사항 중 어느 것도 해당되지 않습니다.", "application.financial.vouchers.nonTaxableIncome.strong": "비과세 소득", "application.financial.vouchers.nonTaxableIncome.text": "SSI, SSDI, 자녀 양육비 또는 산재 보상금과 같은 것들", + "application.financial.vouchers.rentalAssistance": "다른 출처로부터의 임대료 지원", "application.financial.vouchers.rentalSubsidies.strong": "임대료 보조금", "application.financial.vouchers.rentalSubsidies.text": "VASH, HSA, HOPWA, 가톨릭 자선단체, 에이즈 재단 등과 같은 단체들.", + "application.financial.vouchers.subtitleAlt": "다른 출처에서 제공되는 임대료 지원에는 가톨릭 자선 단체나 에이즈 재단과 같은 프로그램의 지원이 포함됩니다.", "application.financial.vouchers.title": "귀하 또는 이 신청서에 포함된 다른 사람이 다음 중 어떤 것을 받고 있습니까?", + "application.financial.vouchers.titleAlt": "귀하 또는 귀하의 가구 구성원 중 누군가가 섹션 8 바우처 또는 주택 공사에서 발행한 바우처(재향군인 지원 주택(VASH) 바우처 포함) 또는 기타 출처로부터 임대료 지원을 받고 있습니까?", "application.form.general.advocateWarning": "귀하는 고객을 대신하여 신청하는 것이므로, 귀하의 정보가 아닌 고객의 정보를 입력하십시오.", "application.form.general.saveAndFinishLater": "저장하고 나중에 완료하세요", "application.form.general.saveAndReturn": "저장하고 검토 화면으로 돌아가기", diff --git a/shared-helpers/src/locales/tl.json b/shared-helpers/src/locales/tl.json index 271f059ee27..dec25c50062 100644 --- a/shared-helpers/src/locales/tl.json +++ b/shared-helpers/src/locales/tl.json @@ -259,12 +259,17 @@ "application.financial.income.validationError.reason.low": "Napakababa ng kita ng iyong sambahayan.", "application.financial.vouchers.housingVouchers.strong": "Mga housing voucher", "application.financial.vouchers.housingVouchers.text": "tulad ng Seksyon 8", + "application.financial.vouchers.issuedVouchers": "Seksyon 8 na Kupon ng Pagpili ng Pabahay", "application.financial.vouchers.legend": "Mga voucher sa pabahay, kita na hindi kinakaltasan ng buwis o mga subsidiya sa pagrenta", + "application.financial.vouchers.none": "Wala sa mga nabanggit", "application.financial.vouchers.nonTaxableIncome.strong": "Kita na hindi kinakaltasan ng buwis", "application.financial.vouchers.nonTaxableIncome.text": "tulad ng SSI, SSDI, mga pagbabayad sa sustento sa anak, o kabayarang benepisyo ng manggagawa", + "application.financial.vouchers.rentalAssistance": "Tulong sa pag-upa mula sa iba pang mga mapagkukunan", "application.financial.vouchers.rentalSubsidies.strong": "Mga subsidiya sa pagrent", "application.financial.vouchers.rentalSubsidies.text": "tulad ng VASH, HSA, HOPWA, Catholic Charities, AIDS Foundation, atbp.", + "application.financial.vouchers.subtitleAlt": "Kasama sa tulong sa pag-upa mula sa ibang mga mapagkukunan ang suporta mula sa mga programang tulad ng Catholic Charities o ng AIDS Foundation.", "application.financial.vouchers.title": "Ikaw ba o sinuman sa application na ito ay tumatanggap ng alinman sa mga sumusunod?", + "application.financial.vouchers.titleAlt": "Ikaw ba o sinuman sa iyong sambahayan ay tumatanggap ng mga voucher na inisyu ng Section 8 o Housing Authority, kabilang ang mga voucher para sa Veterans Affairs Supportive Housing (VASH), o tulong sa pag-upa mula sa ibang mga mapagkukunan?", "application.form.general.advocateWarning": "Nag-aaplay ka para sa isang kliyente; pakilagay ang impormasyon ng iyong kliyente, hindi ang sarili mong impormasyon.", "application.form.general.saveAndFinishLater": "I-save at tapusin pagkatapos", "application.form.general.saveAndReturn": "I-save at ibalik para repasuhin", diff --git a/shared-helpers/src/locales/vi.json b/shared-helpers/src/locales/vi.json index 56ffa806700..e504545256e 100644 --- a/shared-helpers/src/locales/vi.json +++ b/shared-helpers/src/locales/vi.json @@ -259,12 +259,17 @@ "application.financial.income.validationError.reason.low": "Thu nhập hộ gia đình của quý vị quá thấp.", "application.financial.vouchers.housingVouchers.strong": "Phiếu chọn Nhà", "application.financial.vouchers.housingVouchers.text": "như Mục 8 (Section 8)", + "application.financial.vouchers.issuedVouchers": "Phiếu hỗ trợ nhà ở theo chương trình Section 8", "application.financial.vouchers.legend": "Phiếu mua nhà, thu nhập được miễn thuế hoặc trợ cấp tiền thuê nhà", + "application.financial.vouchers.none": "Không có đáp án nào ở trên", "application.financial.vouchers.nonTaxableIncome.strong": "Thu nhập không chịu thuế", "application.financial.vouchers.nonTaxableIncome.text": "như SSI, SSDI, các khoản tiền trợ cấp nuôi con, hoặc các khoản tiền quyền lợi bồi thường cho người lao động", + "application.financial.vouchers.rentalAssistance": "Hỗ trợ tiền thuê nhà từ các nguồn khác", "application.financial.vouchers.rentalSubsidies.strong": "Các khoản trợ cấp tiền thuê nhà", "application.financial.vouchers.rentalSubsidies.text": "như VASH, HSA, HOPWA, Catholic Charities, AIDS Foundation, v.v.", + "application.financial.vouchers.subtitleAlt": "Hỗ trợ tiền thuê nhà từ các nguồn khác bao gồm hỗ trợ từ các chương trình như Catholic Charities hoặc AIDS Foundation.", "application.financial.vouchers.title": "Quý vị hoặc bất kỳ ai trong đơn ghi danh này có nhận được bất kỳ quyền lợi nào sau đây không?", + "application.financial.vouchers.titleAlt": "Bạn hoặc bất kỳ ai trong gia đình bạn có nhận được trợ cấp nhà ở theo Chương trình Section 8 hoặc trợ cấp do Cơ quan Nhà ở cấp, bao gồm cả trợ cấp Nhà ở Hỗ trợ Cựu chiến binh (VASH), hoặc trợ cấp thuê nhà từ các nguồn khác không?", "application.form.general.advocateWarning": "Bạn đang nộp đơn thay mặt cho khách hàng; vui lòng nhập thông tin của khách hàng, chứ không phải thông tin của chính bạn.", "application.form.general.saveAndFinishLater": "Lưu và hoàn thành sau", "application.form.general.saveAndReturn": "Lưu và quay lại để xem", diff --git a/shared-helpers/src/locales/zh.json b/shared-helpers/src/locales/zh.json index 604d71436a8..3c7e079190b 100644 --- a/shared-helpers/src/locales/zh.json +++ b/shared-helpers/src/locales/zh.json @@ -259,12 +259,17 @@ "application.financial.income.validationError.reason.low": "您的家庭收入過低。", "application.financial.vouchers.housingVouchers.strong": "房屋補助券", "application.financial.vouchers.housingVouchers.text": "例如第 8 條款 (Section 8) 補助券", + "application.financial.vouchers.issuedVouchers": "第 8 节住房选择券", "application.financial.vouchers.legend": "住房補助券、免稅收入或房租補貼", + "application.financial.vouchers.none": "以上皆非", "application.financial.vouchers.nonTaxableIncome.strong": "免税收入", "application.financial.vouchers.nonTaxableIncome.text": "例如補充保障收入 (SSI)、社會保障殘疾保險 (SSDI)、子女撫養費或工傷補償福利", + "application.financial.vouchers.rentalAssistance": "来自其他来源的租金援助", "application.financial.vouchers.rentalSubsidies.strong": "租金補貼", "application.financial.vouchers.rentalSubsidies.text": "例如 VASH(退伍軍人事務支持性住房計劃)、HSA、HOPWA(愛滋病患者住房機會)、Catholic Charities(天主教慈善協會)、AIDS Foundation(愛滋病基金會)等。", + "application.financial.vouchers.subtitleAlt": "来自其他来源的租金援助包括天主教慈善机构或艾滋病基金会等项目提供的支持。", "application.financial.vouchers.title": "您或申請表所列的任何人有領取以下任何福利嗎?", + "application.financial.vouchers.titleAlt": "您或您家中的任何人是否领取第 8 条款或住房管理局发放的住房券,包括退伍军人事务部支持性住房 (VASH) 住房券,或从其他来源获得租金援助?", "application.form.general.advocateWarning": "您是代表客户申请的;请输入您客户的信息,而不是您自己的信息。", "application.form.general.saveAndFinishLater": "儲存並於稍後完成", "application.form.general.saveAndReturn": "儲存並返回檢視", diff --git a/shared-helpers/src/types/backend-swagger.ts b/shared-helpers/src/types/backend-swagger.ts index eb6cd2882ca..c03d40554e2 100644 --- a/shared-helpers/src/types/backend-swagger.ts +++ b/shared-helpers/src/types/backend-swagger.ts @@ -7242,7 +7242,7 @@ export interface Application { reasonableAccommodations?: string /** */ - incomeVouchers?: boolean + incomeVouchers?: string[] /** */ income?: string @@ -8274,7 +8274,7 @@ export interface PublicAppsFiltered { reasonableAccommodations?: string /** */ - incomeVouchers?: boolean + incomeVouchers?: string[] /** */ income?: string @@ -8625,7 +8625,7 @@ export interface ApplicationCreate { reasonableAccommodations?: string /** */ - incomeVouchers?: boolean + incomeVouchers?: string[] /** */ income?: string @@ -8961,7 +8961,7 @@ export interface ApplicationUpdate { reasonableAccommodations?: string /** */ - incomeVouchers?: boolean + incomeVouchers?: string[] /** */ income?: string @@ -10785,6 +10785,7 @@ export enum FeatureFlagEnum { "enableMarketingFlyer" = "enableMarketingFlyer", "enableMarketingStatus" = "enableMarketingStatus", "enableMarketingStatusMonths" = "enableMarketingStatusMonths", + "enableMultiselectVoucherQuestion" = "enableMultiselectVoucherQuestion", "enableNeighborhoodAmenities" = "enableNeighborhoodAmenities", "enableNeighborhoodAmenitiesDropdown" = "enableNeighborhoodAmenitiesDropdown", "enableNonRegulatedListings" = "enableNonRegulatedListings", diff --git a/shared-helpers/src/utilities/blankApplication.ts b/shared-helpers/src/utilities/blankApplication.ts index 63eaf13e29d..bbc534dd384 100644 --- a/shared-helpers/src/utilities/blankApplication.ts +++ b/shared-helpers/src/utilities/blankApplication.ts @@ -99,7 +99,7 @@ export const blankApplication = { householdExpectingChanges: null, householdStudent: null, reasonableAccommodations: "", - incomeVouchers: null, + incomeVouchers: [], income: null, incomePeriod: null, householdMember: [], diff --git a/sites/partners/__tests__/components/applications/PaperApplicationForm/sections/FormHouseholdIncome.test.tsx b/sites/partners/__tests__/components/applications/PaperApplicationForm/sections/FormHouseholdIncome.test.tsx index 5150a7232e5..fb45f958af8 100644 --- a/sites/partners/__tests__/components/applications/PaperApplicationForm/sections/FormHouseholdIncome.test.tsx +++ b/sites/partners/__tests__/components/applications/PaperApplicationForm/sections/FormHouseholdIncome.test.tsx @@ -21,7 +21,7 @@ describe("", () => { expect(screen.getByLabelText(/per month/i)).toBeInTheDocument() expect(screen.getByLabelText(/annual income/i)).toBeInTheDocument() expect(screen.getByLabelText(/monthly income/i)).toBeInTheDocument() - expect(screen.getByLabelText(/housing voucher or subsidy/i)).toBeInTheDocument() + expect(screen.getByRole("group", { name: /housing voucher or subsidy/i })).toBeInTheDocument() }) it("should disable income value fields until income period is selected", async () => { diff --git a/sites/partners/__tests__/components/listings/ListingFormActions.test.tsx b/sites/partners/__tests__/components/listings/ListingFormActions.test.tsx index b940406542f..8589ccffb7c 100644 --- a/sites/partners/__tests__/components/listings/ListingFormActions.test.tsx +++ b/sites/partners/__tests__/components/listings/ListingFormActions.test.tsx @@ -13,11 +13,11 @@ import ListingFormActions, { } from "../../../src/components/listings/ListingFormActions" import { mockNextRouter, render } from "../../testUtils" import { - FeatureFlagEnum, UserRoleEnum, Jurisdiction, ListingsStatusEnum, User, + FeatureFlagEnum, } from "@bloom-housing/shared-helpers/src/types/backend-swagger" afterEach(cleanup) diff --git a/sites/partners/__tests__/pages/listings/applications/index.test.tsx b/sites/partners/__tests__/pages/listings/applications/index.test.tsx index 49dea52698f..c22a609ba61 100644 --- a/sites/partners/__tests__/pages/listings/applications/index.test.tsx +++ b/sites/partners/__tests__/pages/listings/applications/index.test.tsx @@ -184,7 +184,8 @@ describe("applications", () => { expect(getByText("Friend")).toBeInTheDocument() expect(getByText("Same address as primary HH:1")).toBeInTheDocument() expect(getByText("Work in region HH:1")).toBeInTheDocument() - expect(getAllByText("Yes")).toHaveLength(4) + expect(getAllByText("Yes")).toHaveLength(3) + expect(getByText("incomeVoucher")).toBeInTheDocument() expect(getByText("Flagged as duplicate")).toBeInTheDocument() expect(getByText("Marked as duplicate")).toBeInTheDocument() expect(getByText("No")).toBeInTheDocument() diff --git a/sites/partners/cypress/e2e/default/05-paperApplication.spec.ts b/sites/partners/cypress/e2e/default/05-paperApplication.spec.ts index 24c67f2e01a..8cb705d56e2 100644 --- a/sites/partners/cypress/e2e/default/05-paperApplication.spec.ts +++ b/sites/partners/cypress/e2e/default/05-paperApplication.spec.ts @@ -29,7 +29,6 @@ describe("Paper Application Tests", () => { }) }) - // TODO: unskip when application flow is connected it("submit with no data", () => { cy.fixture("emptyApplication").then((application) => { cy.fillTerms(application, true) diff --git a/sites/partners/cypress/fixtures/alternateContactOnlyData.json b/sites/partners/cypress/fixtures/alternateContactOnlyData.json index 0e61eb93c7a..48503e7d029 100644 --- a/sites/partners/cypress/fixtures/alternateContactOnlyData.json +++ b/sites/partners/cypress/fixtures/alternateContactOnlyData.json @@ -35,6 +35,7 @@ "incomePeriod": "n/a", "incomeMonth": "n/a", "incomeVouchers": "No", + "vouchers": "n/a", "demographics.ethnicity": "n/a", "acceptedTerms": "Yes", "firstName": "n/a", diff --git a/sites/partners/cypress/fixtures/applicantOnlyData.json b/sites/partners/cypress/fixtures/applicantOnlyData.json index 9ed74656b70..e9b854565c9 100644 --- a/sites/partners/cypress/fixtures/applicantOnlyData.json +++ b/sites/partners/cypress/fixtures/applicantOnlyData.json @@ -35,6 +35,7 @@ "incomePeriod": "n/a", "incomeMonth": "n/a", "incomeVouchers": "No", + "vouchers": "n/a", "demographics.ethnicity": "n/a", "acceptedTerms": "Yes", "firstName": "n/a", diff --git a/sites/partners/cypress/fixtures/application.json b/sites/partners/cypress/fixtures/application.json index 979cc45393d..8a48e24a03f 100644 --- a/sites/partners/cypress/fixtures/application.json +++ b/sites/partners/cypress/fixtures/application.json @@ -35,6 +35,7 @@ "incomePeriod": "Month", "incomeMonth": "5000", "incomeVouchers": "No", + "vouchers": "No", "demographics.ethnicity": "Not Hispanic / Latino", "acceptedTerms": "Yes", "firstName": "HouseHold First Name", diff --git a/sites/partners/cypress/fixtures/demographicsOnlyData.json b/sites/partners/cypress/fixtures/demographicsOnlyData.json index 5fdee713742..9b56bb8ac6b 100644 --- a/sites/partners/cypress/fixtures/demographicsOnlyData.json +++ b/sites/partners/cypress/fixtures/demographicsOnlyData.json @@ -35,6 +35,7 @@ "incomePeriod": "n/a", "incomeMonth": "n/a", "incomeVouchers": "No", + "vouchers": "n/a", "demographics.ethnicity": "Not Hispanic / Latino", "acceptedTerms": "Yes", "firstName": "n/a", diff --git a/sites/partners/cypress/fixtures/emptyApplication.json b/sites/partners/cypress/fixtures/emptyApplication.json index 1d1ae5e586e..b9d8de5d045 100644 --- a/sites/partners/cypress/fixtures/emptyApplication.json +++ b/sites/partners/cypress/fixtures/emptyApplication.json @@ -36,6 +36,7 @@ "incomePeriod": "n/a", "incomeMonth": "n/a", "incomeVouchers": "No", + "vouchers": "n/a", "demographics.ethnicity": "n/a", "acceptedTerms": "Yes", "firstName": "n/a", diff --git a/sites/partners/cypress/fixtures/householdDetailsOnlyData.json b/sites/partners/cypress/fixtures/householdDetailsOnlyData.json index 93d8bff77b8..ff9fb51bc3c 100644 --- a/sites/partners/cypress/fixtures/householdDetailsOnlyData.json +++ b/sites/partners/cypress/fixtures/householdDetailsOnlyData.json @@ -35,6 +35,7 @@ "incomePeriod": "n/a", "incomeMonth": "n/a", "incomeVouchers": "No", + "vouchers": "n/a", "demographics.ethnicity": "n/a", "acceptedTerms": "Yes", "firstName": "n/a", diff --git a/sites/partners/cypress/fixtures/householdIncomeOnlyData.json b/sites/partners/cypress/fixtures/householdIncomeOnlyData.json index 6068fcee776..c51bf6c0091 100644 --- a/sites/partners/cypress/fixtures/householdIncomeOnlyData.json +++ b/sites/partners/cypress/fixtures/householdIncomeOnlyData.json @@ -35,6 +35,7 @@ "incomePeriod": "Month", "incomeMonth": "6000", "incomeVouchers": "Yes", + "vouchers": "Yes", "demographics.ethnicity": "n/a", "acceptedTerms": "Yes", "firstName": "n/a", diff --git a/sites/partners/cypress/fixtures/householdMemberOnlyData.json b/sites/partners/cypress/fixtures/householdMemberOnlyData.json index 818e388730f..51e5d00397d 100644 --- a/sites/partners/cypress/fixtures/householdMemberOnlyData.json +++ b/sites/partners/cypress/fixtures/householdMemberOnlyData.json @@ -35,6 +35,7 @@ "incomePeriod": "n/a", "incomeMonth": "n/a", "incomeVouchers": "No", + "vouchers": "n/a", "demographics.ethnicity": "n/a", "acceptedTerms": "Yes", "firstName": "household", diff --git a/sites/partners/cypress/fixtures/partialApplicationA.json b/sites/partners/cypress/fixtures/partialApplicationA.json index 2570aa22039..7d715850284 100644 --- a/sites/partners/cypress/fixtures/partialApplicationA.json +++ b/sites/partners/cypress/fixtures/partialApplicationA.json @@ -35,6 +35,7 @@ "incomePeriod": "Year", "incomeMonth": "n/a", "incomeVouchers": "No", + "vouchers": "No", "demographics.ethnicity": "n/a", "acceptedTerms": "Yes", "firstName": "n/a", diff --git a/sites/partners/cypress/support/commands.js b/sites/partners/cypress/support/commands.js index 1bf6dadfd24..60e779bcb3a 100644 --- a/sites/partners/cypress/support/commands.js +++ b/sites/partners/cypress/support/commands.js @@ -258,7 +258,13 @@ Cypress.Commands.add("fillHouseholdIncome", (application, fieldsToSkip = []) => cy.getByID("incomeYear").type(application["incomeYear"]) } if (!fieldsToSkip.includes("application.incomeVouchers")) { - cy.getByID("application.incomeVouchers").select(application["incomeVouchers"]) + if (application["incomeVouchers"] === "No") { + cy.getByID(`incomeVoucherNo`).click() + } else if (application["incomeVouchers"] === "Yes") { + cy.getByID(`incomeVoucherYes`).click() + } else { + cy.getByID(`application.incomeVouchers.${application["incomeVouchers"]}`).click() + } } }) @@ -395,7 +401,7 @@ Cypress.Commands.add("verifyHouseholdIncome", (application, fieldsToSkip = []) = const fields = [ { id: "annualIncome", fieldKey: "annualIncome" }, { id: "monthlyIncome", fieldKey: "formattedMonthlyIncome" }, - { id: "vouchers", fieldKey: "incomeVouchers" }, + { id: "vouchers", fieldKey: "vouchers" }, ] verifyHelper(application, fields, fieldsToSkip) }) diff --git a/sites/partners/src/components/applications/ApplicationsColDefs.tsx b/sites/partners/src/components/applications/ApplicationsColDefs.tsx index 7870c1310b0..5ab12c6b572 100644 --- a/sites/partners/src/components/applications/ApplicationsColDefs.tsx +++ b/sites/partners/src/components/applications/ApplicationsColDefs.tsx @@ -213,9 +213,9 @@ export function getColDefs( width: 100, minWidth: 50, valueFormatter: (data) => { - if (!data.value) return "" + if (!data.value || data.value.length === 0) return t("t.no") - return data.value ? t("t.yes") : t("t.no") + return data.value.join(", ") }, comparator: compareStrings, }, diff --git a/sites/partners/src/components/applications/PaperApplicationDetails/sections/DetailsHouseholdIncome.tsx b/sites/partners/src/components/applications/PaperApplicationDetails/sections/DetailsHouseholdIncome.tsx index ec7e2ddca70..1f8e4a87190 100644 --- a/sites/partners/src/components/applications/PaperApplicationDetails/sections/DetailsHouseholdIncome.tsx +++ b/sites/partners/src/components/applications/PaperApplicationDetails/sections/DetailsHouseholdIncome.tsx @@ -6,9 +6,34 @@ import { formatIncome } from "../../../../lib/helpers" import SectionWithGrid from "../../../shared/SectionWithGrid" import { IncomePeriodEnum } from "@bloom-housing/shared-helpers/src/types/backend-swagger" -const DetailsHouseholdIncome = () => { +type DetailsHouseholdIncomeProps = { + enableMultiselectVoucherQuestion?: boolean +} + +const DetailsHouseholdIncome = ({ + enableMultiselectVoucherQuestion, +}: DetailsHouseholdIncomeProps) => { const application = useContext(ApplicationContext) + const renderVouchers = () => { + if (enableMultiselectVoucherQuestion) { + if (!application.incomeVouchers || application.incomeVouchers.length === 0) { + return t("t.n/a") + } + return application.incomeVouchers + .map((v) => t(`application.financial.vouchers.${v}`)) + .join(", ") + } + if (application.incomeVouchers === null || application.incomeVouchers === undefined) { + return t("t.n/a") + } + return application.incomeVouchers?.includes("incomeVoucher") + ? t("t.yes") + : application.incomeVouchers?.includes("none") + ? t("t.no") + : t("t.n/a") + } + return ( @@ -38,15 +63,7 @@ const DetailsHouseholdIncome = () => { - {(() => { - if (application.incomeVouchers === null) return t("t.n/a") - - if (application.incomeVouchers) { - return t("t.yes") - } - - return t("t.no") - })()} + {renderVouchers()} diff --git a/sites/partners/src/components/applications/PaperApplicationForm/PaperApplicationForm.tsx b/sites/partners/src/components/applications/PaperApplicationForm/PaperApplicationForm.tsx index a110b24cddb..5e5bdef0e10 100644 --- a/sites/partners/src/components/applications/PaperApplicationForm/PaperApplicationForm.tsx +++ b/sites/partners/src/components/applications/PaperApplicationForm/PaperApplicationForm.tsx @@ -133,6 +133,13 @@ const ApplicationForm = ({ listingId, editMode, application }: ApplicationFormPr listingDto?.jurisdictions.id ) + const enableMultiselectVoucherQuestion = doJurisdictionsHaveFeatureFlagOn( + FeatureFlagEnum.enableMultiselectVoucherQuestion, + listingDto?.jurisdictions.id + ) + + console.log("enableMultiselectVoucherQuestion", enableMultiselectVoucherQuestion) + const units = listingDto?.units const defaultValues = editMode ? mapApiToForm(application, listingDto, enableV2MSQ) : {} @@ -407,7 +414,9 @@ const ApplicationForm = ({ listingId, editMode, application }: ApplicationFormPr enableV2MSQ={enableV2MSQ} /> - + { +type FormHouseholdIncomeProps = { + enableMultiselectVoucherQuestion?: boolean +} + +const FormHouseholdIncome = ({ enableMultiselectVoucherQuestion }: FormHouseholdIncomeProps) => { const formMethods = useFormContext() // eslint-disable-next-line @typescript-eslint/unbound-method @@ -16,6 +17,8 @@ const FormHouseholdIncome = () => { const incomePeriodValue: string = watch("application.incomePeriod") + const incomeVouchersValue: string[] = watch("application.incomeVouchers") || [] + return ( <>
@@ -86,15 +89,82 @@ const FormHouseholdIncome = () => { -