Skip to content

Commit

Permalink
Merge pull request #171 from companieshouse/feature/update-psc-list-s…
Browse files Browse the repository at this point in the history
…creen

Update psc list screen to version 9 of prototype
  • Loading branch information
AlisonGriffiths authored Nov 21, 2024
2 parents f0df6a9 + d3229aa commit 2f5f655
Show file tree
Hide file tree
Showing 17 changed files with 296 additions and 126 deletions.
26 changes: 22 additions & 4 deletions locales/cy/individual-psc-list.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
{
"individual_psc_list_main_title": "To be translated",
"individual_psc_list_hint_1": "To be translated",
"individual_psc_list_hint_2": "To be translated",
"individual_psc_list_born_in": "To be translated"
"ind_psc_list_main_title": "To be translated",
"ind_psc_list_description": "To be translated",
"ind_psc_list_can_verify_heading": "To be translated",
"ind_psc_list_can_verify_description": "To be translated ",
"ind_psc_list_can_verify_description2": " To be translated",
"ind_psc_list_summary_card_key1": "To be translated",
"ind_psc_list_summary_card_key2": "To be translated",
"ind_psc_list_summary_card_key3": "To be translated",
"ind_psc_list_summary_card_verify_link": "To be translated",
"ind_psc_list_cannot_verify_heading": "To be translated",
"ind_psc_list_cannot_verify_description": "To be translated ",
"ind_psc_list_cannot_verify_description2": "To be translated ",
"ind_psc_list_cannot_verify_description3": ", To be translated",
"ind_psc_list_cannot_verify_details_main_link": "To be translated",
"ind_psc_list_cannot_verify_details_description": "To be translated",
"ind_psc_list_not_found_details_main_link": "To be translated",
"ind_psc_list_not_found_details_description": "To be translated",
"ind_psc_list_not_found_details_description2": "To be translated",
"ind_psc_list_not_found_details_description3": "To be translated ",
"ind_psc_list_not_found_details_description4": "To be translated ",
"ind_psc_list_not_found_details_description5": ", To be translated",
"ind_psc_list_status_unverified": "To be translated"
}
26 changes: 22 additions & 4 deletions locales/en/individual-psc-list.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
{
"individual_psc_list_main_title": "Which PSC are you providing verification details for?",
"individual_psc_list_hint_1": "The following PSCs for",
"individual_psc_list_hint_2": "still need to provide their identity verification details. We will not show PSCs whose identity has been confirmed. You can only provide verification details for one PSC at a time.",
"individual_psc_list_born_in": "Born in"
"ind_psc_list_main_title": "PSC identity verification status",
"ind_psc_list_description": "An overview of which PSCs still need to provide their verification details, and who has done it already.",
"ind_psc_list_can_verify_heading": "PSCs that need to provide verification details",
"ind_psc_list_can_verify_description": "These PSCs for ",
"ind_psc_list_can_verify_description2": " can provide their verification details now. You can only provide details for one PSC at a time.",
"ind_psc_list_summary_card_key1": "Date of birth",
"ind_psc_list_summary_card_key2": "Verification deadline",
"ind_psc_list_summary_card_key3": "Verification status",
"ind_psc_list_summary_card_verify_link": "Provide verification details",
"ind_psc_list_cannot_verify_heading": "PSCs that cannot provide verification details yet",
"ind_psc_list_cannot_verify_description": "These PSCs for ",
"ind_psc_list_cannot_verify_description2": " must wait until ",
"ind_psc_list_cannot_verify_description3": ", which is the company's confirmation statement date. They will have 14 days from this date to provide their verification details.",
"ind_psc_list_cannot_verify_details_main_link": "Why do these PSCs need to wait?",
"ind_psc_list_cannot_verify_details_description": "These PSCs were registered with Companies House before the new identity verification requirements were introduced. We are not able to accept their verification details until the company has reached its confirmation statement date.",
"ind_psc_list_not_found_details_main_link": "I can't find the PSC I'm looking for",
"ind_psc_list_not_found_details_description": "You can only use this service to provide verification details for PSCs that are shown on the Companies House register.",
"ind_psc_list_not_found_details_description2": "If the company has recently notified Companies House of a new PSC, you must wait until that filing is accepted and the new PSC appears on the public register.",
"ind_psc_list_not_found_details_description3": "If a PSC has their personal information protected from being shown on the register, you'll need to provide their verification details using a paper form. To request a form, email ",
"ind_psc_list_not_found_details_description4": "or call ",
"ind_psc_list_not_found_details_description5": ", and provide the company name and number.",
"ind_psc_list_status_unverified": "Unverified"
}
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ export const env = readEnv(process.env, {
DEVELOPERS_LINK: str
.describe("Link for developers")
.default("https://developer.companieshouse.gov.uk/"),
DSR_EMAIL_ADDRESS: str
.describe("Email Address for DSR team")
.default("dsr@companieshouse.gov.uk"),
DSR_PHONE_NUMBER: str
.describe("Telephone number for the DSR team")
.default("02921 507 370"),
FEEDBACK_URL: str
.describe("Link for the user to give feedback on the service")
.default(""),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,30 @@ import { Request, Response } from "express";
import { PrefixedUrls, Urls } from "../../../constants";
import { logger } from "../../../lib/logger";
import { getLocaleInfo, getLocalesService, selectLang } from "../../../utils/localise";
import { addSearchParams } from "../../../utils/queryParams";
import { getUrlWithTransactionIdAndSubmissionId } from "../../../utils/url";
import { BaseViewData, GenericHandler, ViewModel } from "../generic";
import { CompanyPersonWithSignificantControl } from "@companieshouse/api-sdk-node/dist/services/company-psc/types";
import { getCompanyIndividualPscList } from "../../../services/companyPscService";
import { patchPscVerification } from "../../../services/pscVerificationService";
import { formatDateBorn } from "../../utils";

interface PartialDate {
year: string | number,
month: string | number
import { formatDateBorn, internationaliseDate } from "../../utils";
import { env } from "../../../config";

interface PscListData {
pscId: string,
pscName: string,
pscDob: string,
pscVerificationDeadlineDate: string
}

interface RadioButtonData {
text: string,
value: string,
attributes: { [attr: string]: string},
hint?: {
text: string
},
}
interface IndividualPscListViewData extends BaseViewData {
companyName: string,
pscRadioItems: RadioButtonData[],
selectedPscId: string
confirmationStatementDate: string,
dsrEmailAddress: string,
dsrPhoneNumber: string,
pscDetails: PscListData[],
selectedPscId: string | null,
nextPageUrl: string | null
}

export class IndividualPscListHandler extends GenericHandler<IndividualPscListViewData> {
Expand All @@ -40,10 +40,17 @@ export class IndividualPscListHandler extends GenericHandler<IndividualPscListVi
const verification = res.locals.submission;
const companyNumber = verification?.data?.companyNumber as string;
const companyProfile = res.locals.companyProfile;
const dsrEmailAddress = env.DSR_EMAIL_ADDRESS;
const dsrPhoneNumber = env.DSR_PHONE_NUMBER;

let companyName: string = "";
let confirmationStatementDate: string = "";

if (companyProfile) {
companyName = companyProfile.companyName;
if (companyProfile.confirmationStatement) {
confirmationStatementDate = internationaliseDate(companyProfile.confirmationStatement.nextMadeUpTo, lang);
}
}

let individualPscList: CompanyPersonWithSignificantControl[] = [];
Expand All @@ -52,21 +59,27 @@ export class IndividualPscListHandler extends GenericHandler<IndividualPscListVi
}

const selectedPscId = verification?.data?.pscAppointmentId as string;
const queryParams = new URLSearchParams(req.url.split("?")[1]);
queryParams.set("lang", lang);
queryParams.set("pscType", "individual");
const pscType = "individual";

return {
...baseViewData,
...getLocaleInfo(locales, lang),
currentUrl: `${getUrlWithTransactionIdAndSubmissionId(PrefixedUrls.INDIVIDUAL_PSC_LIST, req.params.transactionId, req.params.submissionId)}?${queryParams}`,
backURL: `${getUrlWithTransactionIdAndSubmissionId(PrefixedUrls.PSC_TYPE, req.params.transactionId, req.params.submissionId)}?${queryParams}`,
currentUrl: resolveUrlTemplate(PrefixedUrls.INDIVIDUAL_PSC_LIST),
backURL: resolveUrlTemplate(PrefixedUrls.PSC_TYPE),
nextPageUrl: resolveUrlTemplate(PrefixedUrls.PERSONAL_CODE) + "&selectedPscId=",
companyName,
pscRadioItems: this.getPscIndividualRadioItems(individualPscList, lang),
confirmationStatementDate,
dsrEmailAddress,
dsrPhoneNumber,
pscDetails: this.getPscDetails(individualPscList, lang),
selectedPscId,
templateName: Urls.INDIVIDUAL_PSC_LIST,
backLinkDataEvent: "psc-list-back-link"
};

function resolveUrlTemplate (prefixedUrl: string): string | null {
return addSearchParams(getUrlWithTransactionIdAndSubmissionId(prefixedUrl, req.params.transactionId, req.params.submissionId), { lang, pscType });
}
}

public async executeGet (req: Request, res: Response): Promise<ViewModel<IndividualPscListViewData>> {
Expand Down Expand Up @@ -94,22 +107,16 @@ export class IndividualPscListHandler extends GenericHandler<IndividualPscListVi
return (`${nextPageUrl}?${queryParams}`);
}

private getPscIndividualRadioItems (individualPscList: CompanyPersonWithSignificantControl[], lang: string): RadioButtonData[] {
private getPscDetails (individualPscList: CompanyPersonWithSignificantControl[], lang: string): PscListData[] {
return individualPscList.map(psc => {
const hintText = this.formatHintText(psc.dateOfBirth, lang, psc);
const pscFormattedDob = `${formatDateBorn(psc.dateOfBirth, lang)}`;

return {
value: psc.links.self.split("/").pop() as string,
text: psc.name,
attributes: { "data-event-id": "selected-PSC-radio-option" },
hint: hintText ? {
text: hintText
} : undefined
pscId: psc.links.self.split("/").pop() as string,
pscName: psc.name,
pscDob: pscFormattedDob,
pscVerificationDeadlineDate: "[pscVerificationDate]"
};
});
}

private formatHintText (dob: PartialDate, lang: string, psc: CompanyPersonWithSignificantControl) {
return `${getLocalesService().i18nCh.resolveSingleKey("individual_psc_list_born_in", lang)} ${formatDateBorn(dob, lang)}`;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { BaseViewData, GenericHandler, ViewModel } from "../generic";
import { formatDateBorn } from "../../utils";
import { PscVerificationData, VerificationStatementEnum } from "@companieshouse/api-sdk-node/dist/services/psc-verification-link/types";

interface IndividualStatementViewData extends BaseViewData {pscName: string, selectedStatements: string[], dateOfBirth: string}
interface IndividualStatementViewData extends BaseViewData {pscName: string, selectedStatements: string[], dateOfBirth: string, selectedPscId: string}

export class IndividualStatementHandler extends GenericHandler<IndividualStatementViewData> {

Expand All @@ -25,6 +25,7 @@ export class IndividualStatementHandler extends GenericHandler<IndividualStateme
const lang = selectLang(req.query.lang);
const locales = getLocalesService();
const selectedStatements = verification?.data?.verificationDetails?.verificationStatements || [];
const selectedPscId = verification?.data?.pscAppointmentId;

return {
...baseViewData,
Expand All @@ -35,11 +36,12 @@ export class IndividualStatementHandler extends GenericHandler<IndividualStateme
currentUrl: resolveUrlTemplate(PrefixedUrls.INDIVIDUAL_STATEMENT),
backURL: resolveUrlTemplate(PrefixedUrls.PERSONAL_CODE),
templateName: Urls.INDIVIDUAL_STATEMENT,
backLinkDataEvent: "psc-statement-back-link"
backLinkDataEvent: "psc-statement-back-link",
selectedPscId: selectedPscId
};

function resolveUrlTemplate (prefixedUrl: string): string | null {
return addSearchParams(getUrlWithTransactionIdAndSubmissionId(prefixedUrl, req.params.transactionId, req.params.submissionId), { lang });
return addSearchParams(getUrlWithTransactionIdAndSubmissionId(prefixedUrl, req.params.transactionId, req.params.submissionId), { lang, selectedPscId });
}
}

Expand Down
13 changes: 10 additions & 3 deletions src/routers/handlers/personal-code/personalCodeHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import { getPscIndividual } from "../../../services/pscService";
interface PersonalCodeViewData extends BaseViewData {
pscName: string,
monthBorn: string,
personalCode: string
personalCode: string,
selectedPscId: string
}

export class PersonalCodeHandler extends GenericHandler<PersonalCodeViewData> {
Expand All @@ -24,7 +25,8 @@ export class PersonalCodeHandler extends GenericHandler<PersonalCodeViewData> {

const baseViewData = await super.getViewData(req, res);
const verification: PscVerification = res.locals.submission;
const pscIndividual = await getPscIndividual(req, verification.data.companyNumber as string, verification.data.pscAppointmentId as string);
const selectedPscId = req.query?.selectedPscId as string;
const pscIndividual = await getPscIndividual(req, verification.data.companyNumber as string, selectedPscId);
const lang = selectLang(req.query.lang);
const locales = getLocalesService();

Expand All @@ -41,7 +43,7 @@ export class PersonalCodeHandler extends GenericHandler<PersonalCodeViewData> {
};

function resolveUrlTemplate (prefixedUrl: string): string | null {
return addSearchParams(getUrlWithTransactionIdAndSubmissionId(prefixedUrl, req.params.transactionId, req.params.submissionId), { lang });
return addSearchParams(getUrlWithTransactionIdAndSubmissionId(prefixedUrl, req.params.transactionId, req.params.submissionId), { lang, selectedPscId });
}
}

Expand All @@ -59,11 +61,16 @@ export class PersonalCodeHandler extends GenericHandler<PersonalCodeViewData> {
logger.info(`${PersonalCodeHandler.name} - ${this.executePost.name} called for transaction: ${req.params?.transactionId} and submissionId: ${req.params?.submissionId}`);
const uvid = req.body.personalCode;
const verification: PscVerificationData = {
pscAppointmentId: req.query?.selectedPscId as string,
verificationDetails: {
uvid: uvid
}
};
logger.debug(`${PersonalCodeHandler.name} - ${this.executePost.name} - patching personal code for transaction: ${req.params?.transactionId} and submissionId: ${req.params?.submissionId}`);
await patchPscVerification(req, req.params.transactionId, req.params.submissionId, verification);

const nextPageUrl = getUrlWithTransactionIdAndSubmissionId(PrefixedUrls.INDIVIDUAL_STATEMENT, req.params.transactionId, req.params.submissionId);
const lang = selectLang(req.query.lang);
return (addSearchParams(nextPageUrl, { lang }));
}
}
10 changes: 1 addition & 9 deletions src/routers/personalCodeRouter.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import { NextFunction, Request, Response, Router } from "express";
import { PrefixedUrls } from "../constants";
import { handleExceptions } from "../utils/asyncHandler";
import { PersonalCodeHandler } from "./handlers/personal-code/personalCodeHandler";
import { selectLang } from "../utils/localise";
import { getUrlWithTransactionIdAndSubmissionId } from "../utils/url";
import { addSearchParams } from "../utils/queryParams";

const personalCodeRouter: Router = Router({ mergeParams: true });

Expand All @@ -16,11 +12,7 @@ personalCodeRouter.get("/", handleExceptions(async (req: Request, res: Response)

personalCodeRouter.post("/", handleExceptions(async (req: Request, res: Response, _next: NextFunction) => {
const handler = new PersonalCodeHandler();
await handler.executePost(req, res);

const nextPageUrl = getUrlWithTransactionIdAndSubmissionId(PrefixedUrls.INDIVIDUAL_STATEMENT, req.params.transactionId, req.params.submissionId);
const lang = selectLang(req.query.lang);
res.redirect(addSearchParams(nextPageUrl, { lang }));
res.redirect(await handler.executePost(req, res));
}));

export default personalCodeRouter;
Loading

0 comments on commit 2f5f655

Please sign in to comment.