Skip to content

Commit

Permalink
psp-7075 : Show ACQ team (organization) in project exports
Browse files Browse the repository at this point in the history
  • Loading branch information
Eduardo Herrera authored and Eduardo Herrera committed Nov 3, 2023
1 parent cdd4e5b commit 7e822c2
Show file tree
Hide file tree
Showing 11 changed files with 102 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,14 @@ public AgreementReportModel(PimsAgreement agreement, ClaimsPrincipal user)

private static string GetTeamMemberName(PimsAcquisitionFile file, string teamProfileTypeCode)
{
PimsPerson matchingPerson = file?.PimsAcquisitionFileTeams?.FirstOrDefault(x => x.AcqFlTeamProfileTypeCode == teamProfileTypeCode)?.Person;
return matchingPerson?.GetFullName() ?? string.Empty;
var matchingTeamMember = file?.PimsAcquisitionFileTeams?.FirstOrDefault(x => x.AcqFlTeamProfileTypeCode == teamProfileTypeCode);

if(matchingTeamMember is not null)
{
return matchingTeamMember.PersonId.HasValue ? matchingTeamMember.Person?.GetFullName() : matchingTeamMember.Organization.Name;
}

return string.Empty;
}

private static string GetNullableDate(DateTime? dateTime)
Expand Down
2 changes: 1 addition & 1 deletion source/backend/api/Services/AcquisitionFileService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public List<AcquisitionFileExportModel> GetAcquisitionFileExport(AcquisitionFilt
FileAcquisitionCompleted = fileProperty.file.CompletionDate.HasValue ? fileProperty.file.CompletionDate.Value.ToString("dd-MMM-yyyy") : string.Empty,
FilePhysicalStatus = fileProperty.file.AcqPhysFileStatusTypeCodeNavigation is not null ? fileProperty.file.AcqPhysFileStatusTypeCodeNavigation.Description : string.Empty,
FileAcquisitionType = fileProperty.file.AcquisitionTypeCodeNavigation is not null ? fileProperty.file.AcquisitionTypeCodeNavigation.Description : string.Empty,
FileAcquisitionTeam = string.Join(", ", fileProperty.file.PimsAcquisitionFileTeams.Select(x => x.Person.GetFullName(true))),
FileAcquisitionTeam = string.Join(", ", fileProperty.file.PimsAcquisitionFileTeams.Select(x => x.PersonId.HasValue ? x.Person.GetFullName(true) : x.Organization.Name)),
FileAcquisitionOwners = string.Join(", ", fileProperty.file.PimsAcquisitionOwners.Select(x => x.FormatOwnerName())),
}).ToList();
}
Expand Down
2 changes: 2 additions & 0 deletions source/backend/dal/Models/AcquisitionReportFilterModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@ public class AcquisitionReportFilterModel
public IEnumerable<long> Projects { get; set; }

public IEnumerable<long> AcquisitionTeamPersons { get; set; }

public IEnumerable<long> AcquisitionTeamOrganizations { get; set; }
}
}
9 changes: 9 additions & 0 deletions source/backend/dal/Repositories/AgreementRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,25 @@ public List<PimsAgreement> SearchAgreements(AcquisitionReportFilterModel filter)
{
predicate.And(a => a.AcquisitionFile.ProjectId.HasValue && filter.Projects.Contains(a.AcquisitionFile.ProjectId.Value));
}

if (filter.AcquisitionTeamPersons != null && filter.AcquisitionTeamPersons.Any())
{
predicate.And(a => a.AcquisitionFile.PimsAcquisitionFileTeams.Any(afp => afp.PersonId.HasValue && filter.AcquisitionTeamPersons.Contains((long)afp.PersonId)));
}

if (filter.AcquisitionTeamOrganizations != null && filter.AcquisitionTeamOrganizations.Any())
{
predicate.And(a => a.AcquisitionFile.PimsAcquisitionFileTeams.Any(o => o.OrganizationId.HasValue && filter.AcquisitionTeamOrganizations.Contains((long)o.OrganizationId)));
}

var query = Context.PimsAgreements
.Include(a => a.AgreementTypeCodeNavigation)
.Include(a => a.AcquisitionFile)
.ThenInclude(a => a.PimsAcquisitionFileTeams)
.ThenInclude(afp => afp.Person)
.Include(a => a.AcquisitionFile)
.ThenInclude(a => a.PimsAcquisitionFileTeams)
.ThenInclude(o => o.Organization)
.Include(a => a.AcquisitionFile)
.ThenInclude(a => a.Project)
.Include(a => a.AcquisitionFile)
Expand Down
10 changes: 10 additions & 0 deletions source/backend/dal/Repositories/CompReqFinancialRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ public IEnumerable<PimsCompReqFinancial> SearchCompensationRequisitionFinancials
.ThenInclude(cr => cr.AcquisitionFile)
.ThenInclude(a => a.PimsAcquisitionFileTeams)
.ThenInclude(afp => afp.Person)
.Include(f => f.CompensationRequisition)
.ThenInclude(cr => cr.AcquisitionFile)
.ThenInclude(a => a.PimsAcquisitionFileTeams)
.ThenInclude(o => o.Organization)
.Include(f => f.CompensationRequisition)
.ThenInclude(cr => cr.AcquisitionFile)
.ThenInclude(a => a.Project)
Expand All @@ -71,11 +75,17 @@ public IEnumerable<PimsCompReqFinancial> SearchCompensationRequisitionFinancials
(f.CompensationRequisition.AlternateProjectId.HasValue && filter.Projects.Contains(f.CompensationRequisition.AlternateProjectId.Value)) ||
(!f.CompensationRequisition.AlternateProjectId.HasValue && f.CompensationRequisition.AcquisitionFile.ProjectId.HasValue && filter.Projects.Contains(f.CompensationRequisition.AcquisitionFile.ProjectId.Value)));
}

if (filter.AcquisitionTeamPersons != null && filter.AcquisitionTeamPersons.Any())
{
query = query.Where(f => f.CompensationRequisition.AcquisitionFile.PimsAcquisitionFileTeams.Any(afp => afp.PersonId.HasValue && filter.AcquisitionTeamPersons.Contains((long)afp.PersonId)));
}

if (filter.AcquisitionTeamOrganizations != null && filter.AcquisitionTeamOrganizations.Any())
{
query = query.Where(f => f.CompensationRequisition.AcquisitionFile.PimsAcquisitionFileTeams.Any(o => o.OrganizationId.HasValue && filter.AcquisitionTeamOrganizations.Contains((long)o.OrganizationId)));
}

return query.ToList();
}
}
Expand Down
19 changes: 17 additions & 2 deletions source/backend/tests/unit/api/Models/AgreementReportModelTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ namespace Pims.Api.Test
public class AgreementReportModelTest
{
[Fact]
public void AgreementReportModel_TeamMember()
public void AgreementReportModel_TeamMember_Person()
{
// Arrange
var testAgreement = new Dal.Entities.PimsAgreement();
var propCoord = new PimsAcquisitionFileTeam() { AcqFlTeamProfileTypeCode = "PROPCOORD", Person = new PimsPerson() { Surname = "test" } };
var propCoord = new PimsAcquisitionFileTeam() { AcqFlTeamProfileTypeCode = "PROPCOORD", PersonId = 1, Person = new PimsPerson() { PersonId = 1, Surname = "test" } };
testAgreement.AcquisitionFile = new Dal.Entities.PimsAcquisitionFile() { PimsAcquisitionFileTeams = new List<PimsAcquisitionFileTeam>() { propCoord } };

// Act
Expand All @@ -24,6 +24,21 @@ public void AgreementReportModel_TeamMember()
model.PropertyCoordinator.Should().Be("test");
}

[Fact]
public void AgreementReportModel_TeamMember_Organization()
{
// Arrange
var testAgreement = new Dal.Entities.PimsAgreement();
var propCoord = new PimsAcquisitionFileTeam() { AcqFlTeamProfileTypeCode = "PROPCOORD", OrganizationId = 100, Organization = new PimsOrganization() { OrganizationId = 100, Name = "FORTIS BC" } };
testAgreement.AcquisitionFile = new Dal.Entities.PimsAcquisitionFile() { PimsAcquisitionFileTeams = new List<PimsAcquisitionFileTeam>() { propCoord } };

// Act
var model = new AgreementReportModel(testAgreement, new System.Security.Claims.ClaimsPrincipal());

// Assert
model.PropertyCoordinator.Should().Be("FORTIS BC");
}

[Fact]
public void AgreementReportModel_TeamMember_Null()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { act, render, RenderOptions, screen, userEvent } from '@/utils/test-util

import { ProjectExportTypes } from './models';
import ProjectExportForm, { IProjectExportFormProps } from './ProjectExportForm';
import { getMockOrganization } from '@/mocks/organization.mock';

const history = createMemoryHistory();

Expand Down Expand Up @@ -97,9 +98,14 @@ describe('ProjectExportForm component', () => {
expect(screen.getByText(/776/g)).not.toBeNull();
});

it('displays team members when passed', async () => {
it('displays team members when passed person', async () => {
const { getByDisplayValue } = setup({
teamMembers: [getMockPerson({ id: 1, surname: 'last', firstName: 'first' })],
teamMembers: [
{
personId: 1,
person: getMockPerson({ id: 1, surname: 'last', firstName: 'first' }),
},
],
} as any);

const select = getByDisplayValue(/Select Export Type.../i);
Expand All @@ -111,6 +117,25 @@ describe('ProjectExportForm component', () => {
expect(screen.getByText(/first last/g)).not.toBeNull();
});

it('displays team members when passed organization', async () => {
const { getByDisplayValue } = setup({
teamMembers: [
{
organizationId: 100,
organization: getMockOrganization({ id: 100, name: 'FORTIS BC' }),
},
],
} as any);

const select = getByDisplayValue(/Select Export Type.../i);

await act(async () => {
userEvent.selectOptions(select, ProjectExportTypes.AGREEMENT);
});

expect(screen.getByText(/FORTIS BC/g)).not.toBeNull();
});

it('hides submit, project, team members by default', async () => {
setup({} as any);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as React from 'react';

import { Select, SelectOption } from '@/components/common/form';
import { SectionField } from '@/components/common/Section/SectionField';
import { Api_Person } from '@/models/api/Person';
import { Api_AcquisitionFileTeam } from '@/models/api/AcquisitionFile';
import { Api_Project } from '@/models/api/Project';
import { Api_ExportProjectFilter } from '@/models/api/ProjectFilter';

Expand All @@ -14,7 +14,7 @@ export interface IProjectExportFormProps {
onExportTypeSelected: () => void;
onExport: (filter: Api_ExportProjectFilter) => Promise<void>;
projects: Api_Project[];
teamMembers: Api_Person[];
teamMembers: Api_AcquisitionFileTeam[];
loading: boolean;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ export const ProjectExportFormContent: React.FunctionComponent<IProjectExportFor
});
const teamMembersOptions = teamMembers.map<CodeTypeSelectOption>(x => {
return {
codeType: x?.id?.toString() ?? '',
codeTypeDescription: formatApiPersonNames(x),
codeType: x.personId ? `P-${x.personId}` : `O-${x.organizationId}`,
codeTypeDescription: x.personId ? formatApiPersonNames(x.person) : x.organization?.name ?? '',
};
});

Expand Down
24 changes: 23 additions & 1 deletion source/frontend/src/features/projects/reports/models.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { CodeTypeSelectOption } from '@/components/maps/leaflet/Control/AdvancedFilter/models';
import { Api_ExportProjectFilter } from '@/models/api/ProjectFilter';

type IdSelector = 'O' | 'P';

export class ExportProjectModel {
public exportType: keyof typeof ProjectExportTypes | '' = '';
public projects: CodeTypeSelectOption[] = [];
Expand All @@ -10,7 +12,8 @@ export class ExportProjectModel {
return {
type: this.exportType === '' ? undefined : this.exportType,
projects: this.projects.map(p => +p.codeType),
acquisitionTeamPersons: this.acquisitionTeam.map(t => +t.codeType),
acquisitionTeamPersons: getParameterIdFromOptions(this.acquisitionTeam),
acquisitionTeamOrganizations: getParameterIdFromOptions(this.acquisitionTeam, 'O'),
};
}
}
Expand All @@ -19,3 +22,22 @@ export enum ProjectExportTypes {
COMPENSATION = 'Compensation Requisition Export',
AGREEMENT = 'Agreement Export',
}

const getParameterIdFromOptions = (
options: CodeTypeSelectOption[],
selector: IdSelector = 'P',
): number[] => {
if (!options.length) {
return [];
}

var filteredItems = options.filter(option => String(option.codeType).startsWith(selector));
if (!filteredItems.length) {
return [];
}

return filteredItems.map(x => {
var number = x.codeType.split('-').pop() ?? '';
return parseInt(number) ?? 0;
});
};
1 change: 1 addition & 0 deletions source/frontend/src/models/api/ProjectFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ import { ProjectExportTypes } from '@/features/projects/reports/models';
export interface Api_ExportProjectFilter {
projects: number[];
acquisitionTeamPersons: number[];
acquisitionTeamOrganizations: number[];
type?: keyof typeof ProjectExportTypes;
}

0 comments on commit 7e822c2

Please sign in to comment.