Skip to content

Commit

Permalink
Merge branch 'dev' into psp-7075
Browse files Browse the repository at this point in the history
  • Loading branch information
Eduardo Herrera authored and Eduardo Herrera committed Nov 3, 2023
2 parents e7b424d + be8345a commit e799780
Show file tree
Hide file tree
Showing 14 changed files with 181 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -206,14 +206,13 @@ public IActionResult GetAcquisitionFileOwners([FromRoute] long id)
[HasPermission(Permissions.AcquisitionFileView)]
[HasPermission(Permissions.ContactView)]
[Produces("application/json")]
[ProducesResponseType(typeof(IEnumerable<PersonModel>), 200)]
[ProducesResponseType(typeof(IEnumerable<AcquisitionFileTeamModel>), 200)]
[SwaggerOperation(Tags = new[] { "acquisitionfile" })]
public IActionResult GetAcquisitionTeamMembers()
{
// TODO: This endpoint needs to be fixed to support ORGANIZATIONS as team members (which were introduced by PSP-6960)
var team = _acquisitionService.GetTeamMembers().Where(t => t.Person is not null);
var team = _acquisitionService.GetTeamMembers();

return new JsonResult(_mapper.Map<IEnumerable<PersonModel>>(team.Select(t => t.Person)));
return new JsonResult(_mapper.Map<IEnumerable<AcquisitionFileTeamModel>>(team));
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ public class AcquisitionFilterModel : PageFilter
/// </summary>
public string AcquisitionTeamMemberPersonId { get; set; }

/// <summary>
/// get/set - The MOTI Organization id to search by for acquisition team members.
/// </summary>
public string AcquisitionTeamMemberOrganizationId { get; set; }
#endregion

#region Constructors
Expand Down Expand Up @@ -72,6 +76,7 @@ public AcquisitionFilterModel(Dictionary<string, Microsoft.Extensions.Primitives
this.AcquisitionFileNameOrNumber = filter.GetStringValue(nameof(this.AcquisitionFileNameOrNumber));
this.ProjectNameOrNumber = filter.GetStringValue(nameof(this.ProjectNameOrNumber));
this.AcquisitionTeamMemberPersonId = filter.GetStringValue(nameof(this.AcquisitionTeamMemberPersonId));
this.AcquisitionTeamMemberOrganizationId = filter.GetStringValue(nameof(this.AcquisitionTeamMemberOrganizationId));

this.Sort = filter.GetStringArrayValue(nameof(this.Sort));
}
Expand All @@ -97,6 +102,7 @@ public static explicit operator AcquisitionFilter(AcquisitionFilterModel model)
AcquisitionFileNameOrNumber = model.AcquisitionFileNameOrNumber,
ProjectNameOrNumber = model.ProjectNameOrNumber,
AcquisitionTeamMemberPersonId = model.AcquisitionTeamMemberPersonId,
AcquisitionTeamMemberOrganizationId = model.AcquisitionTeamMemberOrganizationId,

Sort = model.Sort,
};
Expand Down
4 changes: 2 additions & 2 deletions source/backend/api/Pims.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<UserSecretsId>0ef6255f-9ea0-49ec-8c65-c172304b4926</UserSecretsId>
<Version>4.0.0-66.25</Version>
<Version>4.0.0-66.25</Version>
<Version>4.0.0-66.26</Version>
<Version>4.0.0-66.26</Version>
<AssemblyVersion>4.0.0.66</AssemblyVersion>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<ProjectGuid>16BC0468-78F6-4C91-87DA-7403C919E646</ProjectGuid>
Expand Down
11 changes: 10 additions & 1 deletion source/backend/api/Services/AcquisitionFileService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,16 @@ public IEnumerable<PimsAcquisitionFileTeam> GetTeamMembers()
var userRegions = pimsUser.PimsRegionUsers.Select(r => r.RegionCode).ToHashSet();
long? contractorPersonId = pimsUser.IsContractor ? pimsUser.PersonId : null;

return _acqFileRepository.GetTeamMembers(userRegions, contractorPersonId);
var teamMembers = _acqFileRepository.GetTeamMembers(userRegions, contractorPersonId);

var persons = teamMembers.Where(x => x.Person != null).GroupBy(x => x.PersonId).Select(x => x.First()).ToList();
var organizations = teamMembers.Where(x => x.Organization != null).GroupBy(x => x.OrganizationId).Select(x => x.First()).ToList();

List<PimsAcquisitionFileTeam> teamFilterOptions = new();
teamFilterOptions.AddRange(persons);
teamFilterOptions.AddRange(organizations);

return teamFilterOptions;
}

public IEnumerable<PimsAcquisitionChecklistItem> GetChecklistItems(long id)
Expand Down
6 changes: 6 additions & 0 deletions source/backend/dal/Models/AcquisitionFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ public class AcquisitionFilter : PageFilter
/// get/set - The MOTI person id to search by for acquisition team members.
/// </summary>
public string AcquisitionTeamMemberPersonId { get; set; }

/// <summary>
/// get/set - The MOTI Organization id to search by for acquisition team members.
/// </summary>
public string AcquisitionTeamMemberOrganizationId { get; set; }

#endregion

#region Constructors
Expand Down
15 changes: 11 additions & 4 deletions source/backend/dal/Repositories/AcquisitionFileRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -587,12 +587,12 @@ public List<PimsAcquisitionFileTeam> GetTeamMembers(HashSet<short> regions, long
predicate.And(x => x.AcquisitionFile.PimsAcquisitionFileTeams.Any(p => p.PersonId == contractorPersonId));
}

return Context.PimsAcquisitionFileTeams.Include(x => x.AcquisitionFile)
return Context.PimsAcquisitionFileTeams.AsNoTracking()
.Include(x => x.AcquisitionFile)
.Include(x => x.Person)
.AsNoTracking()
.Include(x => x.Organization)
.Where(predicate)
.AsEnumerable()
.DistinctBy(x => x.PersonId).ToList();
.ToList();
}

/// <summary>
Expand Down Expand Up @@ -787,6 +787,11 @@ private IQueryable<PimsAcquisitionFile> GetCommonAquisitionFileQueryDeep(Acquisi
predicate = predicate.And(acq => acq.PimsAcquisitionFileTeams.Any(x => x.PersonId == long.Parse(filter.AcquisitionTeamMemberPersonId)));
}

if (!string.IsNullOrWhiteSpace(filter.AcquisitionTeamMemberOrganizationId))
{
predicate = predicate.And(acq => acq.PimsAcquisitionFileTeams.Any(x => x.OrganizationId == long.Parse(filter.AcquisitionTeamMemberOrganizationId)));
}

var query = Context.PimsAcquisitionFiles.AsNoTracking()
.Include(r => r.RegionCodeNavigation)
.Include(p => p.Project)
Expand All @@ -796,6 +801,8 @@ private IQueryable<PimsAcquisitionFile> GetCommonAquisitionFileQueryDeep(Acquisi
.Include(t => t.AcquisitionTypeCodeNavigation)
.Include(tm => tm.PimsAcquisitionFileTeams)
.ThenInclude(c => c.Person)
.Include(tm => tm.PimsAcquisitionFileTeams)
.ThenInclude(c => c.Organization)
.Include(tm => tm.PimsAcquisitionFileTeams)
.ThenInclude(c => c.AcqFlTeamProfileTypeCodeNavigation)
.Include(ow => ow.PimsAcquisitionOwners)
Expand Down
2 changes: 1 addition & 1 deletion source/frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "frontend",
"version": "4.0.0-66.25",
"version": "4.0.0-66.26",
"private": true,
"dependencies": {
"@bcgov/bc-sans": "1.0.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Form, Input, Multiselect, Select } from '@/components/common/form';
import { SelectInput } from '@/components/common/List/SelectInput';
import { ACQUISITION_FILE_STATUS_TYPES } from '@/constants/API';
import useLookupCodeHelpers from '@/hooks/useLookupCodeHelpers';
import { Api_Person } from '@/models/api/Person';
import { Api_AcquisitionFileTeam } from '@/models/api/AcquisitionFile';
import { mapLookupCode } from '@/utils';
import { formatApiPersonNames } from '@/utils/personUtils';

Expand All @@ -17,7 +17,7 @@ import { AcquisitionFilterModel, Api_AcquisitionFilter, MultiSelectOption } from
export interface IAcquisitionFilterProps {
filter?: Api_AcquisitionFilter;
setFilter: (filter: Api_AcquisitionFilter) => void;
aquisitionTeam: Api_Person[];
aquisitionTeam: Api_AcquisitionFileTeam[];
}

/**
Expand All @@ -42,8 +42,8 @@ export const AcquisitionFilter: React.FC<React.PropsWithChildren<IAcquisitionFil
};

const onResetClick = (formikProps: FormikProps<AcquisitionFilterModel>) => {
formikProps.resetForm();
resetFilter();
formikProps.resetForm();
};

const lookupCodes = useLookupCodeHelpers();
Expand All @@ -55,8 +55,8 @@ export const AcquisitionFilter: React.FC<React.PropsWithChildren<IAcquisitionFil
const acquisitionTeamOptions = useMemo(() => {
if (aquisitionTeam !== undefined) {
return aquisitionTeam?.map<MultiSelectOption>(x => ({
id: x?.id?.toString() || '',
text: formatApiPersonNames(x),
id: x.personId ? `P-${x.personId}` : `O-${x.organizationId}`,
text: x.personId ? formatApiPersonNames(x.person) : x.organization?.name ?? '',
}));
} else {
return [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,42 @@ describe('Acquisition Search Results Table', () => {
expect(getByText('Alt Project: 1 alternate project')).toBeVisible();
expect(queryByText('[+1 more...]')).toBeNull();
});

it('displays a team member as Organization', async () => {
const { getByText } = setup({
results: [
{
aquisitionTeam: [
{
id: 4,
acquisitionFileId: 5,
organizationId: 6,
organization: {
id: 6,
isDisabled: false,
name: 'FORTIS BC',
alias: 'FORTIS',
incorporationNumber: '123456789',
organizationPersons: [],
organizationAddresses: [],
contactMethods: [],
comment: '',
rowVersion: 1,
},
primaryContactId: 8,
teamProfileTypeCode: 'PROPANLYS',
teamProfileType: {
id: 'PROPANLYS',
description: 'Property analyst',
isDisabled: false,
},
rowVersion: 1,
},
],
},
],
});

expect(getByText('FORTIS BC (Property analyst)')).toBeVisible();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { ColumnWithProps, renderTypeCode } from '@/components/Table';
import { Claims } from '@/constants/claims';
import { useKeycloakWrapper } from '@/hooks/useKeycloakWrapper';
import { Api_AcquisitionFileTeam } from '@/models/api/AcquisitionFile';
import { Api_Organization } from '@/models/api/Organization';
import { Api_Person } from '@/models/api/Person';
import { Api_Project } from '@/models/api/Project';
import Api_TypeCode from '@/models/api/TypeCode';
Expand All @@ -16,9 +17,10 @@ import { formatApiPersonNames } from '@/utils/personUtils';
import AcquisitionProperties from './AcquisitionProperties';
import { AcquisitionSearchResultModel } from './models';

interface PersonRoleGroup {
interface MemberRoleGroup {
id: string;
person: Api_Person;
person: Api_Person | null;
organization: Api_Organization | null;
roles: string[];
}

Expand Down Expand Up @@ -109,28 +111,56 @@ export const columns: ColumnWithProps<AcquisitionSearchResultModel>[] = [
maxWidth: 40,
Cell: (props: CellProps<AcquisitionSearchResultModel>) => {
const acquisitionTeam = props.row.original.aquisitionTeam;
const teamAsString: PersonRoleGroup[] = chain(acquisitionTeam)
const personsInTeam = acquisitionTeam?.filter(x => x.personId !== undefined);
const organizationsInTeam = acquisitionTeam?.filter(x => x.organizationId !== undefined);

const personsAsString: MemberRoleGroup[] = chain(personsInTeam)
.groupBy((groupedTeams: Api_AcquisitionFileTeam) => groupedTeams.personId)
.map<PersonRoleGroup>(x => {
.map<MemberRoleGroup>(x => {
return {
id: x[0].id?.toString() || '',
person: x[0].person || {},
organization: null,
roles: x
.map(t => t.teamProfileType)
.filter((z): z is Api_TypeCode<string> => z !== undefined)
.flatMap(y => y.description || ''),
};
})
.value();

const organizationsAsString: MemberRoleGroup[] = chain(organizationsInTeam)
.groupBy((groupedTeams: Api_AcquisitionFileTeam) => groupedTeams.organizationId)
.map<MemberRoleGroup>(x => {
return {
id: x[0].id?.toString() || '',
person: null,
organization: x[0].organization || {},
roles: x
.map(t => t.teamProfileType)
.filter((z): z is Api_TypeCode<string> => z !== undefined)
.flatMap(y => y.description || ''),
};
})
.value();

const teamAsString = personsAsString.concat(organizationsAsString);

return (
<ExpandableTextList<PersonRoleGroup>
<ExpandableTextList<MemberRoleGroup>
items={teamAsString ?? []}
keyFunction={(item: PersonRoleGroup, index: number) =>
`aquisition-team-${item.id}-person-${item.person.id ?? index}`
keyFunction={(item: MemberRoleGroup, index: number) =>
item.person
? `aquisition-team-${item.id}-person-${item.person.id ?? index}`
: `aquisition-team-${item.id}-org-${item.organization?.id ?? index}`
}
renderFunction={(item: MemberRoleGroup) =>
item.person ? (
<>{`${formatApiPersonNames(item.person)} (${item.roles.join(', ')})`}</>
) : (
<>{`${item.organization?.name} (${item.roles.join(', ')})`}</>
)
}
renderFunction={(item: PersonRoleGroup) => (
<>{`${formatApiPersonNames(item.person)} (${item.roles.join(', ')})`}</>
)}
delimiter={', '}
maxCollapsedLength={2}
/>
Expand Down
Loading

0 comments on commit e799780

Please sign in to comment.