Skip to content

Commit

Permalink
AB#30601 Personal Info generic attributes refactor (#6285)
Browse files Browse the repository at this point in the history
Added missing attributes to profile page

Signed-off-by: Ruben <vandervalk@geoit.nl>
Co-authored-by: Ruben <vandervalk@geoit.nl>
  • Loading branch information
RubenGeo and Ruben authored Dec 19, 2024
1 parent 0bca75b commit 1442d28
Show file tree
Hide file tree
Showing 9 changed files with 356 additions and 78 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import {
GenericRegistrationAttributes,
RegistrationAttributeTypes,
} from '@121-service/src/registration/enum/registration-attribute.enum';
import { LanguageEnum } from '@121-service/src/shared/enum/language.enums';
import { LocalizedString } from '@121-service/src/shared/types/localized-string.type';

import { DataListItem } from '~/components/data-list/data-list.component';
import { AttributeWithTranslatedLabel } from '~/domains/project/project.model';
import { LANGUAGE_ENUM_LABEL } from '~/domains/registration/registration.helper';

export const ATTRIBUTE_LABELS: Record<GenericRegistrationAttributes, string> = {
referenceId: $localize`:@@attribute-label-referenceId:Reference ID`,
phoneNumber: $localize`:@@attribute-label-phoneNumber:Phone Number`,
preferredLanguage: $localize`:@@attribute-label-preferredLanguage:Preferred Language`,
paymentAmountMultiplier: $localize`:@@attribute-label-paymentAmountMultiplier:Transfer value multiplier`,
programFinancialServiceProviderConfigurationName: $localize`:@@attribute-label-programFinancialServiceProviderConfigurationName:FSP Configuration Name`,
programFinancialServiceProviderConfigurationLabel: $localize`:@@attribute-label-programFinancialServiceProviderConfigurationLabel:FSP`,
maxPayments: $localize`:@@attribute-label-maxPayments:Max. payments`,
paymentCount: $localize`:@@attribute-label-paymentCount:Payment Count`,
paymentCountRemaining: $localize`:@@attribute-label-paymentCountRemaining:Remaining payments`,
scope: $localize`:@@attribute-label-scope:Scope`,
status: $localize`:@@attribute-label-status:Status`,
registrationProgramId: $localize`:@@attribute-label-registrationProgramId:Registration ID`,
registrationCreatedDate: $localize`:@@attribute-label-registrationCreatedDate:Registration Created Date`,
inclusionScore: $localize`:@@attribute-label-inclusionScore:Inclusion Score`,
};

export const getGenericAttributeDataListItem = (
attributeName: GenericRegistrationAttributes,
value: unknown,
): DataListItem => {
const label = ATTRIBUTE_LABELS[attributeName];
switch (attributeName) {
case GenericRegistrationAttributes.paymentAmountMultiplier:
case GenericRegistrationAttributes.maxPayments:
case GenericRegistrationAttributes.paymentCountRemaining:
case GenericRegistrationAttributes.inclusionScore:
case GenericRegistrationAttributes.paymentCount:
return {
label,
type: 'number',
value: value as null | number,
};
case GenericRegistrationAttributes.preferredLanguage:
case GenericRegistrationAttributes.programFinancialServiceProviderConfigurationLabel:
case GenericRegistrationAttributes.referenceId:
case GenericRegistrationAttributes.phoneNumber:
case GenericRegistrationAttributes.programFinancialServiceProviderConfigurationName:
case GenericRegistrationAttributes.scope:
case GenericRegistrationAttributes.status:
case GenericRegistrationAttributes.registrationProgramId:
return {
label,
type: 'text',
value: value as LocalizedString | null | string,
};
case GenericRegistrationAttributes.registrationCreatedDate:
return {
label,
type: 'date',
value: value as Date | null,
};
}
};

export const getValueForGenericAttribute = (
value: unknown,
attributeName: GenericRegistrationAttributes,
): unknown => {
switch (attributeName) {
case GenericRegistrationAttributes.preferredLanguage:
return LANGUAGE_ENUM_LABEL[value as LanguageEnum];
default:
return value;
}
};

export const projectAttributeToDataListItem = (
attribute: AttributeWithTranslatedLabel,
value: unknown,
): DataListItem | undefined => {
const label = attribute.label;

switch (attribute.type) {
case RegistrationAttributeTypes.multiSelect:
// TODO: Implement multiSelect when necessary
console.log(
'attributeToDataListItem: multiSelect not implemented',
value,
);
return undefined;
case RegistrationAttributeTypes.numeric:
return {
label,
type: 'number',
value: value as number,
};
case RegistrationAttributeTypes.numericNullable:
return {
label,
type: 'number',
value: value as null | number,
};
case RegistrationAttributeTypes.date:
return {
label,
type: 'date',
value: value as Date,
};
case RegistrationAttributeTypes.boolean:
return {
label,
type: 'boolean',
value: value as boolean,
};
case RegistrationAttributeTypes.dropdown:
case RegistrationAttributeTypes.tel:
case RegistrationAttributeTypes.text:
return {
label,
type: 'text',
value: value as LocalizedString | string,
};
}
};

export const isGenericAttribute = (
name: string,
): name is GenericRegistrationAttributes => name in ATTRIBUTE_LABELS;
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { ExportType } from '@121-service/src/metrics/enum/export-type.enum';
import { CommercialBankEthiopiaValidationReportDto } from '@121-service/src/payments/fsp-integration/commercial-bank-ethiopia/dto/commercial-bank-ethiopia-validation-report.dto';

import { DomainApiService } from '~/domains/domain-api.service';
import { ATTRIBUTE_LABELS } from '~/domains/project/project.helper';
import {
Attribute,
AttributeWithTranslatedLabel,
Expand All @@ -16,6 +15,10 @@ import {
ProjectUserAssignment,
ProjectUserWithRolesLabel,
} from '~/domains/project/project.model';
import {
ATTRIBUTE_LABELS,
isGenericAttribute,
} from '~/domains/project/project-attribute.helpers';
import { Role } from '~/domains/role/role.model';
import { TranslatableStringService } from '~/services/translatable-string.service';
import { Dto } from '~/utils/dto-type';
Expand Down Expand Up @@ -103,12 +106,13 @@ export class ProjectApiService extends DomainApiService {
const translatedLabel = this.translatableStringService.translate(
attribute.label,
);

return {
...attribute,
label:
translatedLabel ??
ATTRIBUTE_LABELS[attribute.name] ??
(isGenericAttribute(attribute.name)
? ATTRIBUTE_LABELS[attribute.name]
: undefined) ??
attribute.name,
};
});
Expand Down
75 changes: 12 additions & 63 deletions interfaces/Portalicious/src/app/domains/project/project.helper.ts
Original file line number Diff line number Diff line change
@@ -1,73 +1,11 @@
import { FinancialServiceProviderIntegrationType } from '@121-service/src/financial-service-providers/financial-service-provider-integration-type.enum';
import { RegistrationAttributeTypes } from '@121-service/src/registration/enum/registration-attribute.enum';
import { LocalizedString } from '@121-service/src/shared/types/localized-string.type';

import { DataListItem } from '~/components/data-list/data-list.component';
import { getFinancialServiceProviderSettingByName } from '~/domains/financial-service-provider/financial-service-provider.helper';
import {
FSPS_WITH_PHYSICAL_CARD_SUPPORT,
FSPS_WITH_VOUCHER_SUPPORT,
} from '~/domains/payment/payment.helpers';
import {
AttributeWithTranslatedLabel,
Project,
} from '~/domains/project/project.model';

export const ATTRIBUTE_LABELS: Record<string, string | undefined> = {
fspDisplayName: $localize`:@@attribute-label-fspDisplayName:FSP Display Name`,
paymentAmountMultiplier: $localize`:@@attribute-label-paymentAmountMultiplier:Transfer value multiplier`,
maxPayments: $localize`:@@attribute-label-maxPayments:Max. payments`,
paymentCountRemaining: $localize`:@@attribute-label-paymentCountRemaining:Remaining payments`,
};

export const attributeToDataListItem = (
attribute: AttributeWithTranslatedLabel,
value: unknown,
): DataListItem | undefined => {
const label = attribute.label;

switch (attribute.type) {
case RegistrationAttributeTypes.multiSelect:
// TODO: Implement multiSelect when necessary
console.log(
'attributeToDataListItem: multiSelect not implemented',
value,
);
return undefined;
case RegistrationAttributeTypes.numeric:
return {
label,
type: 'number',
value: value as number,
};
case RegistrationAttributeTypes.numericNullable:
return {
label,
type: 'number',
value: value as null | number,
};
case RegistrationAttributeTypes.date:
return {
label,
type: 'date',
value: value as Date,
};
case RegistrationAttributeTypes.boolean:
return {
label,
type: 'boolean',
value: value as boolean,
};
case RegistrationAttributeTypes.dropdown:
case RegistrationAttributeTypes.tel:
case RegistrationAttributeTypes.text:
return {
label,
type: 'text',
value: value as LocalizedString | string,
};
}
};
import { Project } from '~/domains/project/project.model';

export function projectHasVoucherSupport(project?: Project) {
return project?.programFinancialServiceProviderConfigurations.some((fsp) =>
Expand All @@ -89,6 +27,17 @@ export function projectHasFspWithExportFileIntegration(project?: Project) {
);
}

export function projectHasInclusionScore(project?: Project): boolean {
if (project?.programRegistrationAttributes) {
for (const attribute of project.programRegistrationAttributes) {
if (Object.keys(attribute.scoring).length > 0) {
return true;
}
}
}
return false;
}

export function financialServiceProviderConfigurationNamesHaveIntegrationType({
project,
financialServiceProviderConfigurationNames,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ActivityTypeEnum } from '@121-service/src/activities/enum/activity-type.enum';
import { VisaCard121Status } from '@121-service/src/payments/fsp-integration/intersolve-visa/enums/wallet-status-121.enum';
import { RegistrationStatusEnum } from '@121-service/src/registration/enum/registration-status.enum';
import { LanguageEnum } from '@121-service/src/shared/enum/language.enums';

import { AppRoutes } from '~/app.routes';
import { ChipVariant } from '~/components/colored-chip/colored-chip.component';
Expand Down Expand Up @@ -53,6 +54,18 @@ export const REGISTRATION_STATUS_VERB: Record<RegistrationStatusEnum, string> =
[RegistrationStatusEnum.deleted]: $localize`Delete`,
};

export const LANGUAGE_ENUM_LABEL: Record<LanguageEnum, string> = {
ar: $localize`Arabic`,
en: $localize`English`,
es: $localize`Spanish`,
fr: $localize`French`,
in: $localize`Indonesian`,
nl: $localize`Dutch`,
pt_BR: $localize`Portuguese`,
tl: $localize`Filipino`,
tr: $localize`Turkish`,
};

export const VISA_CARD_STATUS_LABELS: Record<VisaCard121Status, string> = {
[VisaCard121Status.Active]: $localize`:@@debit-card-status-active:Active`,
[VisaCard121Status.Issued]: $localize`:@@debit-card-status-issued:Issued`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,20 @@ import { InputTextModule } from 'primeng/inputtext';
import { SelectButtonModule } from 'primeng/selectbutton';
import { TabMenuModule } from 'primeng/tabmenu';

import { GenericRegistrationAttributes } from '@121-service/src/registration/enum/registration-attribute.enum';

import {
DataListComponent,
DataListItem,
} from '~/components/data-list/data-list.component';
import { RegistrationPageLayoutComponent } from '~/components/registration-page-layout/registration-page-layout.component';
import { ProjectApiService } from '~/domains/project/project.api.service';
import { attributeToDataListItem } from '~/domains/project/project.helper';
import { projectHasInclusionScore } from '~/domains/project/project.helper';
import {
getGenericAttributeDataListItem,
getValueForGenericAttribute,
projectAttributeToDataListItem,
} from '~/domains/project/project-attribute.helpers';
import { RegistrationApiService } from '~/domains/registration/registration.api.service';

@Component({
Expand Down Expand Up @@ -51,7 +58,7 @@ export class ProjectRegistrationPersonalInformationPageComponent {
this.projectApiService.getProjectAttributes({
projectId: this.projectId,
includeProgramRegistrationAttributes: true,
includeTemplateDefaultAttributes: true,
includeTemplateDefaultAttributes: false,
}),
);

Expand All @@ -62,20 +69,54 @@ export class ProjectRegistrationPersonalInformationPageComponent {
),
);

project = injectQuery(this.projectApiService.getProject(this.projectId));

attributeList = computed<DataListItem[]>(() => {
const list: DataListItem[] = [];
if (!this.projectAttributes.isSuccess() || !this.registration.isSuccess()) {
return list;
}

const genericAttributeNames =
this.genericAttributeNamesForPersonalInformation();
for (const attributeName of genericAttributeNames) {
const value = getValueForGenericAttribute(
this.registration.data()[attributeName],
attributeName,
);
const genericAttributeListItem = getGenericAttributeDataListItem(
attributeName,
value,
);
list.push(genericAttributeListItem);
}
for (const attribute of this.projectAttributes.data()) {
const value = this.registration.data()[attribute.name] as unknown;
const dataListItem = attributeToDataListItem(attribute, value);
const dataListItem = projectAttributeToDataListItem(attribute, value);
if (dataListItem) {
list.push(dataListItem);
}
}

return list;
});

private genericAttributeNamesForPersonalInformation = computed<
GenericRegistrationAttributes[]
>(() => {
const genericAttributeNames: GenericRegistrationAttributes[] = [
GenericRegistrationAttributes.preferredLanguage,
GenericRegistrationAttributes.programFinancialServiceProviderConfigurationLabel,
GenericRegistrationAttributes.paymentAmountMultiplier,
];
if (this.project.data()?.enableMaxPayments) {
genericAttributeNames.concat([
GenericRegistrationAttributes.maxPayments,
GenericRegistrationAttributes.paymentCountRemaining,
]);
}
if (projectHasInclusionScore(this.project.data())) {
genericAttributeNames.push(GenericRegistrationAttributes.inclusionScore);
}
return genericAttributeNames;
});
}
Loading

0 comments on commit 1442d28

Please sign in to comment.