From 35fff26af5f89840709a48fbd76155e02e429ebb Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Sat, 21 Oct 2023 15:40:03 -0700 Subject: [PATCH 1/2] PSP-7002 : H0443: Show Acq team (organization) on document --- .../hooks/useGenerateH0443.test.tsx | 120 ++++++++++++++++++ .../GenerateForm/hooks/useGenerateH0443.ts | 74 +++++++++-- .../src/mocks/acquisitionFiles.mock.ts | 2 + 3 files changed, 183 insertions(+), 13 deletions(-) diff --git a/source/frontend/src/features/mapSideBar/acquisition/common/GenerateForm/hooks/useGenerateH0443.test.tsx b/source/frontend/src/features/mapSideBar/acquisition/common/GenerateForm/hooks/useGenerateH0443.test.tsx index 84aeae0c5d..77e1bc420c 100644 --- a/source/frontend/src/features/mapSideBar/acquisition/common/GenerateForm/hooks/useGenerateH0443.test.tsx +++ b/source/frontend/src/features/mapSideBar/acquisition/common/GenerateForm/hooks/useGenerateH0443.test.tsx @@ -9,6 +9,8 @@ import { useApiContacts } from '@/hooks/pims-api/useApiContacts'; import { useAcquisitionProvider } from '@/hooks/repositories/useAcquisitionProvider'; import { useProperties } from '@/hooks/repositories/useProperties'; import { mockAcquisitionFileResponse } from '@/mocks/acquisitionFiles.mock'; +import { getMockPerson } from '@/mocks/contacts.mock'; +import { getMockOrganization } from '@/mocks/organization.mock'; import { Api_AcquisitionFile } from '@/models/api/AcquisitionFile'; import { Api_Property } from '@/models/api/Property'; @@ -18,6 +20,7 @@ const getPropertiesFn = jest.fn(); const generateFn = jest.fn(); const getAcquisitionFileFn = jest.fn(); const getPersonConceptFn = jest.fn(); +const getOrganizationConceptFn = jest.fn(); jest.mock('@/features/documents/hooks/useDocumentGenerationRepository'); (useDocumentGenerationRepository as jest.Mock).mockImplementation(() => ({ @@ -37,6 +40,7 @@ jest.mock('@/hooks/repositories/useProperties'); jest.mock('@/hooks/pims-api/useApiContacts'); (useApiContacts as jest.Mock).mockImplementation(() => ({ getPersonConcept: getPersonConceptFn, + getOrganizationConcept: getOrganizationConceptFn, })); let currentStore: MockStoreEnhanced; @@ -102,6 +106,122 @@ describe('useGenerateH0443 functions', () => { }); }); + it('makes requests to Organization when Property Coordinator is an organization with a Primary Contact', async () => { + const organizationPersonMock = getMockPerson({ id: 3, firstName: 'JONH', surname: 'Doe' }); + getPersonConceptFn.mockResolvedValue(Promise.resolve({ data: organizationPersonMock })); + + const organizationMock = getMockOrganization(); + getOrganizationConceptFn.mockResolvedValue(Promise.resolve({ data: organizationMock })); + + const responseWithTeam: Api_AcquisitionFile = { + ...mockAcquisitionFileResponse(), + acquisitionTeam: [ + { + id: 1, + acquisitionFileId: 1, + teamProfileTypeCode: 'PROPCOORD', + rowVersion: 2, + organizationId: 100, + primaryContactId: 3, + }, + ], + }; + const generate = setup({ acquisitionResponse: responseWithTeam }); + + await act(async () => { + await generate(0); + expect(generateFn).toHaveBeenCalled(); + expect(getPersonConceptFn).toHaveBeenLastCalledWith(3); + expect(getOrganizationConceptFn).toHaveBeenCalledTimes(1); + }); + }); + + it('makes requests to Organization when Property Coordinator is an organization and no Primary Contact', async () => { + const organizationPersonMock = getMockPerson({ id: 3, firstName: 'JONH', surname: 'Doe' }); + getPersonConceptFn.mockResolvedValue(Promise.resolve({ data: organizationPersonMock })); + + const organizationMock = getMockOrganization(); + getOrganizationConceptFn.mockResolvedValue(Promise.resolve({ data: organizationMock })); + + const responseWithTeam: Api_AcquisitionFile = { + ...mockAcquisitionFileResponse(), + acquisitionTeam: [ + { + id: 1, + acquisitionFileId: 1, + teamProfileTypeCode: 'PROPCOORD', + rowVersion: 2, + organizationId: 100, + }, + ], + }; + const generate = setup({ acquisitionResponse: responseWithTeam }); + + await act(async () => { + await generate(0); + expect(generateFn).toHaveBeenCalled(); + expect(getOrganizationConceptFn).toHaveBeenCalledTimes(1); + expect(getPersonConceptFn).not.toHaveBeenCalled(); + }); + }); + + it('makes requests to Organization when Property Agent is an organization with Primary Contact', async () => { + const organizationMock = getMockOrganization(); + const organizationPersonMock = getMockPerson({ id: 3, firstName: 'JONH', surname: 'Doe' }); + getOrganizationConceptFn.mockResolvedValue(Promise.resolve({ data: organizationMock })); + getPersonConceptFn.mockResolvedValue(Promise.resolve({ data: organizationPersonMock })); + + const responseWithTeam: Api_AcquisitionFile = { + ...mockAcquisitionFileResponse(), + acquisitionTeam: [ + { + id: 2, + acquisitionFileId: 1, + teamProfileTypeCode: 'PROPAGENT', + organizationId: 2, + primaryContactId: 3, + rowVersion: 2, + }, + ], + }; + const generate = setup({ acquisitionResponse: responseWithTeam }); + + await act(async () => { + await generate(0); + expect(generateFn).toHaveBeenCalled(); + expect(getOrganizationConceptFn).toHaveBeenCalledTimes(1); + expect(getPersonConceptFn).toHaveBeenCalledWith(3); + }); + }); + + it('makes requests to Organization when Property Agent is an organization with no Primary Contact', async () => { + const organizationMock = getMockOrganization(); + const organizationPersonMock = getMockPerson({ id: 3, firstName: 'JONH', surname: 'Doe' }); + getOrganizationConceptFn.mockResolvedValue(Promise.resolve({ data: organizationMock })); + getPersonConceptFn.mockResolvedValue(Promise.resolve({ data: organizationPersonMock })); + + const responseWithTeam: Api_AcquisitionFile = { + ...mockAcquisitionFileResponse(), + acquisitionTeam: [ + { + id: 2, + acquisitionFileId: 1, + teamProfileTypeCode: 'PROPAGENT', + organizationId: 2, + rowVersion: 2, + }, + ], + }; + const generate = setup({ acquisitionResponse: responseWithTeam }); + + await act(async () => { + await generate(0); + expect(generateFn).toHaveBeenCalled(); + expect(getOrganizationConceptFn).toHaveBeenCalledTimes(1); + expect(getPersonConceptFn).not.toHaveBeenCalled(); + }); + }); + it('makes requests to expected api endpoints if there are properties', async () => { const responseWithTeam: Api_AcquisitionFile = { ...mockAcquisitionFileResponse(), diff --git a/source/frontend/src/features/mapSideBar/acquisition/common/GenerateForm/hooks/useGenerateH0443.ts b/source/frontend/src/features/mapSideBar/acquisition/common/GenerateForm/hooks/useGenerateH0443.ts index 9ef4e9246f..0e3881217c 100644 --- a/source/frontend/src/features/mapSideBar/acquisition/common/GenerateForm/hooks/useGenerateH0443.ts +++ b/source/frontend/src/features/mapSideBar/acquisition/common/GenerateForm/hooks/useGenerateH0443.ts @@ -11,7 +11,7 @@ import { Api_GeneratePerson } from '@/models/generate/GeneratePerson'; import { Api_GenerateProperty } from '@/models/generate/GenerateProperty'; export const useGenerateH0443 = () => { - const { getPersonConcept } = useApiContacts(); + const { getPersonConcept, getOrganizationConcept } = useApiContacts(); const { getAcquisitionFile: { execute: getAcquisitionFile }, } = useAcquisitionProvider(); @@ -29,19 +29,12 @@ export const useGenerateH0443 = () => { const propertyCoordinator = file.acquisitionTeam?.find( team => team.teamProfileTypeCode === 'PROPCOORD', ); - const coordinatorPerson = !!propertyCoordinator?.personId - ? (await getPersonConcept(propertyCoordinator?.personId))?.data - : null; // Retrieve Property Agent const propertyAgent = file.acquisitionTeam?.find( team => team.teamProfileTypeCode === 'PROPAGENT', ); - const agentPerson = !!propertyAgent?.personId - ? (await getPersonConcept(propertyAgent?.personId))?.data - : null; - // Retrieve Properties const filePropertiesIds = file.fileProperties?.map(fp => fp.propertyId).filter((p): p is number => !!p) || []; @@ -51,7 +44,7 @@ export const useGenerateH0443 = () => { file.acquisitionFileOwners?.filter((x): x is Api_AcquisitionFileOwner => !!x) || []; const contactOwner = owners.find(x => x.isPrimaryContact === true); - const h0443Data: H0443Data = { + let h0443Data: H0443Data = { file_name: file.fileName || '', file_number: file.fileNumber || '', project_number: file.project?.code || '', @@ -62,10 +55,65 @@ export const useGenerateH0443 = () => { : [], owner_names: owners.map(x => getOwnerName(x)) || [], owner_contact: contactOwner !== undefined ? new Api_GenerateOwner(contactOwner) : null, - property_coordinator: new Api_GeneratePerson(coordinatorPerson), - property_agent: new Api_GeneratePerson(agentPerson), + property_coordinator: null, + property_agent: null, }; + // Get the property coordinator by checking if it's a person or an org. + if (propertyCoordinator) { + if (propertyCoordinator.personId) { + const personConceptResponse = await getPersonConcept(propertyCoordinator?.personId); + + h0443Data.property_coordinator = personConceptResponse?.data + ? new Api_GeneratePerson(personConceptResponse.data) + : null; + } else if (propertyCoordinator.organizationId) { + const organizationConceptResponse = await getOrganizationConcept( + propertyCoordinator?.organizationId, + ); + + if ( + organizationConceptResponse && + organizationConceptResponse?.data && + organizationConceptResponse?.data.organizationPersons?.length && + propertyCoordinator.primaryContactId + ) { + const personResponse = await getPersonConcept(propertyCoordinator.primaryContactId); + + h0443Data.property_coordinator = personResponse.data + ? new Api_GeneratePerson(personResponse.data) + : null; + } + } + } + + // Get the property agent by checking if it's a person or an org. + if (propertyAgent) { + if (propertyAgent.personId) { + const personResponse = await getPersonConcept(propertyAgent?.personId); + + h0443Data.property_agent = personResponse?.data + ? new Api_GeneratePerson(personResponse.data) + : null; + } else if (propertyAgent.organizationId) { + const organizationConceptResponse = await getOrganizationConcept( + propertyAgent?.organizationId, + ); + + if ( + organizationConceptResponse.data && + organizationConceptResponse?.data.organizationPersons?.length && + propertyAgent.primaryContactId + ) { + const personResponse = await getPersonConcept(propertyAgent.primaryContactId); + + h0443Data.property_agent = personResponse.data + ? new Api_GeneratePerson(personResponse.data) + : null; + } + } + } + const generatedFile = await generate({ templateType: FormDocumentType.H0443, templateData: h0443Data, @@ -102,6 +150,6 @@ interface H0443Data { project_number: string; project_name: string; properties: Api_GenerateProperty[]; - property_agent: Api_GeneratePerson; - property_coordinator: Api_GeneratePerson; + property_agent: Api_GeneratePerson | null; + property_coordinator: Api_GeneratePerson | null; } diff --git a/source/frontend/src/mocks/acquisitionFiles.mock.ts b/source/frontend/src/mocks/acquisitionFiles.mock.ts index f8693d822b..d6cb2f81ca 100644 --- a/source/frontend/src/mocks/acquisitionFiles.mock.ts +++ b/source/frontend/src/mocks/acquisitionFiles.mock.ts @@ -143,6 +143,7 @@ export const mockAcquisitionFileResponse = ( { id: 1, acquisitionFileId: 1, + personId: 1, person: { id: 1, isDisabled: false, @@ -166,6 +167,7 @@ export const mockAcquisitionFileResponse = ( { id: 2, acquisitionFileId: 1, + personId: 3, person: { id: 3, isDisabled: false, From 2dbea5ef47813e350892260f8a96b5d070844b5a Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Mon, 23 Oct 2023 09:18:35 -0700 Subject: [PATCH 2/2] - updates --- .../hooks/useGenerateH0443.test.tsx | 65 +++++++++---------- .../GenerateForm/hooks/useGenerateH0443.ts | 18 ++--- 2 files changed, 36 insertions(+), 47 deletions(-) diff --git a/source/frontend/src/features/mapSideBar/acquisition/common/GenerateForm/hooks/useGenerateH0443.test.tsx b/source/frontend/src/features/mapSideBar/acquisition/common/GenerateForm/hooks/useGenerateH0443.test.tsx index 77e1bc420c..a576c0cd1e 100644 --- a/source/frontend/src/features/mapSideBar/acquisition/common/GenerateForm/hooks/useGenerateH0443.test.tsx +++ b/source/frontend/src/features/mapSideBar/acquisition/common/GenerateForm/hooks/useGenerateH0443.test.tsx @@ -71,13 +71,15 @@ const setup = (params?: { storeValues?: any; acquisitionResponse?: Api_Acquisiti describe('useGenerateH0443 functions', () => { it('makes requests to expected api endpoints', async () => { const generate = setup(); - await act(async () => { - await generate(0); - expect(generateFn).toHaveBeenCalled(); - }); + await act(async () => await generate(0)); + + expect(generateFn).toHaveBeenCalled(); }); it('makes requests to expected api endpoints for each required team member', async () => { + const organizationPersonMock = getMockPerson({ id: 3, firstName: 'JONH', surname: 'Doe' }); + getPersonConceptFn.mockResolvedValue(Promise.resolve({ data: organizationPersonMock })); + const responseWithTeam: Api_AcquisitionFile = { ...mockAcquisitionFileResponse(), acquisitionTeam: [ @@ -99,11 +101,10 @@ describe('useGenerateH0443 functions', () => { }; const generate = setup({ acquisitionResponse: responseWithTeam }); - await act(async () => { - await generate(0); - expect(generateFn).toHaveBeenCalled(); - expect(getPersonConceptFn).toHaveBeenCalledTimes(2); - }); + await act(async () => await generate(0)); + + expect(generateFn).toHaveBeenCalled(); + expect(getPersonConceptFn).toHaveBeenCalledTimes(2); }); it('makes requests to Organization when Property Coordinator is an organization with a Primary Contact', async () => { @@ -111,7 +112,7 @@ describe('useGenerateH0443 functions', () => { getPersonConceptFn.mockResolvedValue(Promise.resolve({ data: organizationPersonMock })); const organizationMock = getMockOrganization(); - getOrganizationConceptFn.mockResolvedValue(Promise.resolve({ data: organizationMock })); + getOrganizationConceptFn.mockResolvedValue({ data: organizationMock }); const responseWithTeam: Api_AcquisitionFile = { ...mockAcquisitionFileResponse(), @@ -128,12 +129,11 @@ describe('useGenerateH0443 functions', () => { }; const generate = setup({ acquisitionResponse: responseWithTeam }); - await act(async () => { - await generate(0); - expect(generateFn).toHaveBeenCalled(); - expect(getPersonConceptFn).toHaveBeenLastCalledWith(3); - expect(getOrganizationConceptFn).toHaveBeenCalledTimes(1); - }); + await act(async () => await generate(0)); + + expect(generateFn).toHaveBeenCalled(); + expect(getPersonConceptFn).toHaveBeenLastCalledWith(3); + expect(getOrganizationConceptFn).toHaveBeenCalledTimes(1); }); it('makes requests to Organization when Property Coordinator is an organization and no Primary Contact', async () => { @@ -157,12 +157,11 @@ describe('useGenerateH0443 functions', () => { }; const generate = setup({ acquisitionResponse: responseWithTeam }); - await act(async () => { - await generate(0); - expect(generateFn).toHaveBeenCalled(); - expect(getOrganizationConceptFn).toHaveBeenCalledTimes(1); - expect(getPersonConceptFn).not.toHaveBeenCalled(); - }); + await act(async () => await generate(0)); + + expect(generateFn).toHaveBeenCalled(); + expect(getOrganizationConceptFn).toHaveBeenCalledTimes(1); + expect(getPersonConceptFn).not.toHaveBeenCalled(); }); it('makes requests to Organization when Property Agent is an organization with Primary Contact', async () => { @@ -186,12 +185,11 @@ describe('useGenerateH0443 functions', () => { }; const generate = setup({ acquisitionResponse: responseWithTeam }); - await act(async () => { - await generate(0); - expect(generateFn).toHaveBeenCalled(); - expect(getOrganizationConceptFn).toHaveBeenCalledTimes(1); - expect(getPersonConceptFn).toHaveBeenCalledWith(3); - }); + await act(async () => generate(0)); + + expect(generateFn).toHaveBeenCalled(); + expect(getOrganizationConceptFn).toHaveBeenCalledTimes(1); + expect(getPersonConceptFn).toHaveBeenCalledWith(3); }); it('makes requests to Organization when Property Agent is an organization with no Primary Contact', async () => { @@ -214,12 +212,11 @@ describe('useGenerateH0443 functions', () => { }; const generate = setup({ acquisitionResponse: responseWithTeam }); - await act(async () => { - await generate(0); - expect(generateFn).toHaveBeenCalled(); - expect(getOrganizationConceptFn).toHaveBeenCalledTimes(1); - expect(getPersonConceptFn).not.toHaveBeenCalled(); - }); + await act(async () => await generate(0)); + + expect(generateFn).toHaveBeenCalled(); + expect(getOrganizationConceptFn).toHaveBeenCalledTimes(1); + expect(getPersonConceptFn).not.toHaveBeenCalled(); }); it('makes requests to expected api endpoints if there are properties', async () => { diff --git a/source/frontend/src/features/mapSideBar/acquisition/common/GenerateForm/hooks/useGenerateH0443.ts b/source/frontend/src/features/mapSideBar/acquisition/common/GenerateForm/hooks/useGenerateH0443.ts index 0e3881217c..36b6e9f6ec 100644 --- a/source/frontend/src/features/mapSideBar/acquisition/common/GenerateForm/hooks/useGenerateH0443.ts +++ b/source/frontend/src/features/mapSideBar/acquisition/common/GenerateForm/hooks/useGenerateH0443.ts @@ -44,7 +44,7 @@ export const useGenerateH0443 = () => { file.acquisitionFileOwners?.filter((x): x is Api_AcquisitionFileOwner => !!x) || []; const contactOwner = owners.find(x => x.isPrimaryContact === true); - let h0443Data: H0443Data = { + const h0443Data: H0443Data = { file_name: file.fileName || '', file_number: file.fileNumber || '', project_number: file.project?.code || '', @@ -64,9 +64,7 @@ export const useGenerateH0443 = () => { if (propertyCoordinator.personId) { const personConceptResponse = await getPersonConcept(propertyCoordinator?.personId); - h0443Data.property_coordinator = personConceptResponse?.data - ? new Api_GeneratePerson(personConceptResponse.data) - : null; + h0443Data.property_coordinator = new Api_GeneratePerson(personConceptResponse.data); } else if (propertyCoordinator.organizationId) { const organizationConceptResponse = await getOrganizationConcept( propertyCoordinator?.organizationId, @@ -80,9 +78,7 @@ export const useGenerateH0443 = () => { ) { const personResponse = await getPersonConcept(propertyCoordinator.primaryContactId); - h0443Data.property_coordinator = personResponse.data - ? new Api_GeneratePerson(personResponse.data) - : null; + h0443Data.property_coordinator = new Api_GeneratePerson(personResponse.data); } } } @@ -92,9 +88,7 @@ export const useGenerateH0443 = () => { if (propertyAgent.personId) { const personResponse = await getPersonConcept(propertyAgent?.personId); - h0443Data.property_agent = personResponse?.data - ? new Api_GeneratePerson(personResponse.data) - : null; + h0443Data.property_agent = new Api_GeneratePerson(personResponse.data); } else if (propertyAgent.organizationId) { const organizationConceptResponse = await getOrganizationConcept( propertyAgent?.organizationId, @@ -107,9 +101,7 @@ export const useGenerateH0443 = () => { ) { const personResponse = await getPersonConcept(propertyAgent.primaryContactId); - h0443Data.property_agent = personResponse.data - ? new Api_GeneratePerson(personResponse.data) - : null; + h0443Data.property_agent = new Api_GeneratePerson(personResponse.data); } } }