diff --git a/src/pages/addUserFlow/addUser/components/AddUserForm/AddUserForm.tsx b/src/pages/addUserFlow/addUser/components/AddUserForm/AddUserForm.tsx index eb6e1b7..c531a7e 100644 --- a/src/pages/addUserFlow/addUser/components/AddUserForm/AddUserForm.tsx +++ b/src/pages/addUserFlow/addUser/components/AddUserForm/AddUserForm.tsx @@ -94,8 +94,8 @@ export default function AddUserForm({ const { hasPermission } = usePermissions(); const onExit = useUnloadEventOnExit(); const { isPnpgTheOnlyProduct, pnpgProduct, activeOnboardings, isAdminEaOnProdIO } = - useAddUserFormComputedValues(party, products); - const { validate, validTaxcode, setValidTaxcode } = useFormValidation(t); + useAddUserFormComputedValues(party, products, userProduct); + const { validate, validTaxcode, setValidTaxcode } = useFormValidation(t, isAdminEaOnProdIO); useEffect(() => { if (!initialFormData.taxCode) { @@ -441,7 +441,10 @@ export default function AddUserForm({ /> } aria-label={t(titleKey)} - onClick={() => formik.setFieldValue('toAddOnAggregates', value, true)} + onClick={async () => { + setIsAddInBulkEAFlow(value); + await formik.setFieldValue('toAddOnAggregates', value, true); + }} /> ))} diff --git a/src/pages/addUserFlow/addUser/components/AddUserForm/hooks/useAddUserFormLogic.tsx b/src/pages/addUserFlow/addUser/components/AddUserForm/hooks/useAddUserFormLogic.tsx index ac9a047..d11da62 100644 --- a/src/pages/addUserFlow/addUser/components/AddUserForm/hooks/useAddUserFormLogic.tsx +++ b/src/pages/addUserFlow/addUser/components/AddUserForm/hooks/useAddUserFormLogic.tsx @@ -2,18 +2,26 @@ import { useState } from 'react'; import { Party } from '../../../../../../model/Party'; import { PartyUserOnCreation } from '../../../../../../model/PartyUser'; import { Product } from '../../../../../../model/Product'; +import { PRODUCT_IDS } from '../../../../../../utils/constants'; import { validateUserForm } from '../utils/addUserFormUtils'; -export const useAddUserFormComputedValues = (party: Party, products: Array) => { - const isPnpgTheOnlyProduct = - !!products.find((p) => p.id === 'prod-pn-pg') && products.length === 1; - const pnpgProduct = products.find((p) => p.id === 'prod-pn-pg'); +export const useAddUserFormComputedValues = ( + party: Party, + products: Array, + userProduct: Product | undefined +) => { + const isPnpgTheOnlyProduct = !!products.find( + (p) => p.id === PRODUCT_IDS.PNPG && products.length === 1 + ); + const pnpgProduct = products.find((p) => p.id === PRODUCT_IDS.PNPG); const activeOnboardings = party.products.filter((p) => p.productOnBoardingStatus === 'ACTIVE'); - const isAdminEaOnProdIO = party.products.some( - (p) => p.productOnBoardingStatus === 'ACTIVE' && p.productId === 'prod-io' && p.isAggregator - ); + const isAdminEaOnProdIO = + party.products.some( + (p) => + p.productOnBoardingStatus === 'ACTIVE' && p.productId === PRODUCT_IDS.IO && p.isAggregator + ) && userProduct?.id === PRODUCT_IDS.IO; return { isPnpgTheOnlyProduct, @@ -24,11 +32,11 @@ export const useAddUserFormComputedValues = (party: Party, products: Array { +export const useFormValidation = (t: any, isAdminEaOnProdIO: boolean) => { const [validTaxcode, setValidTaxcode] = useState(); const validate = (values: Partial) => { - const errors = validateUserForm(values, t); + const errors = validateUserForm(values, t, isAdminEaOnProdIO); if (!errors.taxCode) { setValidTaxcode(values.taxCode); diff --git a/src/pages/addUserFlow/addUser/components/AddUserForm/utils/addUserFormUtils.ts b/src/pages/addUserFlow/addUser/components/AddUserForm/utils/addUserFormUtils.ts index d4ecec7..3159259 100644 --- a/src/pages/addUserFlow/addUser/components/AddUserForm/utils/addUserFormUtils.ts +++ b/src/pages/addUserFlow/addUser/components/AddUserForm/utils/addUserFormUtils.ts @@ -1,50 +1,70 @@ import { emailRegexp } from '@pagopa/selfcare-common-frontend/lib/utils/constants'; -import { verifyChecksumMatchWithTaxCode } from '@pagopa/selfcare-common-frontend/lib/utils/verifyChecksumMatchWithTaxCode'; -import { verifyNameMatchWithTaxCode } from '@pagopa/selfcare-common-frontend/lib/utils/verifyNameMatchWithTaxCode'; -import { verifySurnameMatchWithTaxCode } from '@pagopa/selfcare-common-frontend/lib/utils/verifySurnameMatchWithTaxCode'; import { FormikProps } from 'formik'; import { PartyUserOnCreation } from '../../../../../../model/PartyUser'; import { UserRegistry } from '../../../../../../model/UserRegistry'; -import { requiredError, taxCodeRegexp } from '../../../../utils/validation'; +import { + requiredError, + validateName, + validateSurname, + validateTaxCode, +} from '../../../../utils/validation'; + +const validateEmail = (email: string | undefined, t: (key: string) => string) => { + if (!email) { + return requiredError; + } + if (!emailRegexp.test(email)) { + return t('userEdit.addForm.errors.invalidEmail'); + } + return undefined; +}; + +const validateConfirmEmail = ( + confirmEmail: string | undefined, + email: string | undefined, + t: (key: string) => string +) => { + if (!confirmEmail) { + return requiredError; + } + if (email && confirmEmail.toLocaleLowerCase() !== email.toLocaleLowerCase()) { + return t('userEdit.addForm.errors.mismatchEmail'); + } + return undefined; +}; + +const validateProductRoles = (productRoles: Array | undefined) => + productRoles?.length === 0 ? requiredError : undefined; + +const validateToAddOnAggregates = (toAddOnAggregates: any, isAdminEaOnProdIO: boolean) => { + // Only validate if isAdminEaOnProdIO is true + if (!isAdminEaOnProdIO) { + return undefined; + } + + return toAddOnAggregates === undefined ? requiredError : undefined; +}; -// Pure validation utilities export const validateUserForm = ( values: Partial, - t: (key: string) => string - // eslint-disable-next-line sonarjs/cognitive-complexity -) => - Object.fromEntries( - Object.entries({ - name: !values.name - ? requiredError - : verifyNameMatchWithTaxCode(values.name, values.taxCode) - ? t('userEdit.mismatchWithTaxCode.name') - : undefined, - surname: !values.surname - ? requiredError - : verifySurnameMatchWithTaxCode(values.surname, values.taxCode) - ? t('userEdit.mismatchWithTaxCode.surname') - : undefined, - taxCode: !values.taxCode - ? requiredError - : !taxCodeRegexp.test(values.taxCode) || verifyChecksumMatchWithTaxCode(values.taxCode) - ? t('userEdit.addForm.errors.invalidFiscalCode') - : undefined, - email: !values.email - ? requiredError - : !emailRegexp.test(values.email) - ? t('userEdit.addForm.errors.invalidEmail') - : undefined, - confirmEmail: !values.confirmEmail - ? requiredError - : values.email && - values.confirmEmail.toLocaleLowerCase() !== values.email.toLocaleLowerCase() - ? t('userEdit.addForm.errors.mismatchEmail') - : undefined, - productRoles: values.productRoles?.length === 0 ? requiredError : undefined, - toAddOnAggregates: values.toAddOnAggregates === undefined ? requiredError : undefined, - }).filter(([_key, value]) => value) + t: (key: string) => string, + isAdminEaOnProdIO: boolean +) => { + const validationResults = { + name: validateName(values.name, values.taxCode, t), + surname: validateSurname(values.surname, values.taxCode, t), + taxCode: validateTaxCode(values.taxCode, t), + email: validateEmail(values.email, t), + confirmEmail: validateConfirmEmail(values.confirmEmail, values.email, t), + productRoles: validateProductRoles(values.productRoles), + toAddOnAggregates: validateToAddOnAggregates(values.toAddOnAggregates, isAdminEaOnProdIO), + }; + + // Filter out undefined values (no errors) + return Object.fromEntries( + Object.entries(validationResults).filter(([_key, value]) => value !== undefined) ); +}; // Pure utility functions export const isAddRoleFromDashboard = (phasesAdditionAllowed?: Array) => @@ -55,12 +75,12 @@ export const isAddRoleFromDashboardAsync = (phasesAdditionAllowed?: Array string +) => { + if (!name) { + return requiredError; + } + if (verifyNameMatchWithTaxCode(name, taxCode)) { + return t('userEdit.mismatchWithTaxCode.name'); + } + return undefined; +}; + +export const validateSurname = ( + surname: string | undefined, + taxCode: string | undefined, + t: (key: string) => string +) => { + if (!surname) { + return requiredError; + } + if (verifySurnameMatchWithTaxCode(surname, taxCode)) { + return t('userEdit.mismatchWithTaxCode.surname'); + } + return undefined; +}; + +export const validateTaxCode = (taxCode: string | undefined, t: (key: string) => string) => { + if (!taxCode) { + return requiredError; + } + if (!taxCodeRegexp.test(taxCode) || verifyChecksumMatchWithTaxCode(taxCode)) { + return t('userEdit.addForm.errors.invalidFiscalCode'); + } + return undefined; +}; + export const validateManagerForm = ( manager: Partial, addedUserList: Array, @@ -38,21 +76,9 @@ export const validateManagerForm = ( return Object.fromEntries( Object.entries({ - name: !manager.name - ? requiredField - : verifyNameMatchWithTaxCode(manager.name, manager.taxCode) - ? t('userEdit.mismatchWithTaxCode.name') - : undefined, - surname: !manager.surname - ? requiredField - : verifySurnameMatchWithTaxCode(manager.surname, manager.taxCode) - ? t('userEdit.mismatchWithTaxCode.surname') - : undefined, - taxCode: !manager.taxCode - ? requiredField - : !taxCodeRegexp.test(manager.taxCode) || verifyChecksumMatchWithTaxCode(manager.taxCode) - ? t('userEdit.addForm.errors.invalidFiscalCode') - : undefined, + name: validateName(manager.name, manager.taxCode, t), + surname: validateSurname(manager.surname, manager.taxCode, t), + taxCode: validateTaxCode(manager.taxCode, t), email: !manager.email ? requiredField : !emailRegexp.test(manager.email)