diff --git a/ess/src/API/EMBC.ESS/Resources/Tasks/Contract.cs b/ess/src/API/EMBC.ESS/Resources/Tasks/Contract.cs
index 58409ae88..7a985a616 100644
--- a/ess/src/API/EMBC.ESS/Resources/Tasks/Contract.cs
+++ b/ess/src/API/EMBC.ESS/Resources/Tasks/Contract.cs
@@ -47,11 +47,15 @@ public record EssTask : Task
public bool RemoteExtensionsEnabled { get; set; }
public bool SelfServeEnabled { get; set; }
public IEnumerable EnabledSupports { get; set; } = [];
+ public IEnumerable SupportLimits { get; set; } = [];
}
public record SupportConfiguration
{
public SupportType SupportType { get; set; }
+ public DateTime SupportLimitStartDate { get; set; }
+ public DateTime SupportLimitEndDate { get; set; }
+ public bool ExtensionAvailable { get; set; }
}
public enum SupportType
diff --git a/ess/src/API/EMBC.ESS/Resources/Tasks/Mappings.cs b/ess/src/API/EMBC.ESS/Resources/Tasks/Mappings.cs
index e384e6cae..ce9ebd7d4 100644
--- a/ess/src/API/EMBC.ESS/Resources/Tasks/Mappings.cs
+++ b/ess/src/API/EMBC.ESS/Resources/Tasks/Mappings.cs
@@ -20,10 +20,28 @@ public Mappings()
.ForMember(d => d.SelfServeEnabled, opts => opts.MapFrom(s => s.era_selfservetoggle))
.ForMember(d => d.AutoApprovedEnabled, opts => opts.Ignore())
.ForMember(d => d.EnabledSupports, opts => opts.MapFrom(s => s.era_era_task_era_selfservesupportlimits_Task.Where(sl => sl.statuscode == 1)))
+ .ForMember(d => d.SupportLimits, opts => opts.MapFrom(s => s.era_era_task_era_supportlimit_Task.Where(sl => sl.statuscode == 1)))
;
CreateMap()
.ForMember(d => d.SupportType, opts => opts.MapFrom(s => s.era_supporttypeoption))
+ .ForMember(d => d.ExtensionAvailable, opts => opts.MapFrom(s => s.era_extensionavailable))
+ .ForMember(d => d.SupportLimitStartDate, opts => opts.MapFrom(s => s.era_supportlimitstartdate.HasValue ? s.era_supportlimitstartdate.Value.UtcDateTime : (DateTime?)null))
+ .ForMember(d => d.SupportLimitEndDate, opts => opts.MapFrom(s => s.era_supportlimitenddate.HasValue ? s.era_supportlimitenddate.Value.UtcDateTime : (DateTime?)null))
;
+
+ CreateMap()
+ .ForMember(d => d.SupportType, opts => opts.MapFrom(s => s.era_supporttypeoption))
+ .ForMember(d => d.ExtensionAvailable, opts => opts.MapFrom(s => s.era_extensionavailable))
+ .ForMember(d => d.SupportLimitStartDate, opts => opts.MapFrom(s => s.era_supportlimitstartdate.HasValue ? s.era_supportlimitstartdate.Value.UtcDateTime : (DateTime?)null))
+ .ForMember(d => d.SupportLimitEndDate, opts => opts.MapFrom(s => s.era_supportlimitenddate.HasValue ? s.era_supportlimitenddate.Value.UtcDateTime : (DateTime?)null))
+ ;
+
+ CreateMap()
+ .ForMember(dest => dest.SupportType, opts => opts.MapFrom(src => src.SupportType))
+ .ForMember(dest => dest.SupportLimitStartDate, opts => opts.MapFrom(src => src.SupportLimitStartDate))
+ .ForMember(dest => dest.SupportLimitEndDate, opts => opts.MapFrom(src => src.SupportLimitEndDate))
+ .ForMember(dest => dest.ExtensionAvailable, opts => opts.MapFrom(src => src.ExtensionAvailable))
+ ;
}
}
diff --git a/ess/src/API/EMBC.ESS/Resources/Tasks/TaskRepository.cs b/ess/src/API/EMBC.ESS/Resources/Tasks/TaskRepository.cs
index 85ec512ba..553599e45 100644
--- a/ess/src/API/EMBC.ESS/Resources/Tasks/TaskRepository.cs
+++ b/ess/src/API/EMBC.ESS/Resources/Tasks/TaskRepository.cs
@@ -65,6 +65,7 @@ private async Task> QueryTasks(TaskQuery query, Cancellati
essContext.era_tasks
.Expand(t => t.era_JurisdictionID)
.Expand(t => t.era_era_task_era_selfservesupportlimits_Task)
+ .Expand(t => t.era_era_task_era_supportlimit_Task)
.Where(t => t.era_name == query.ById)
.GetAllPagesAsync(ct)).ToList();
@@ -72,6 +73,9 @@ await Parallel.ForEachAsync(tasks, ct, async (t, ct1) =>
{
var selfServeSupports = (await essContext.era_selfservesupportlimitses.Expand(sl => sl.era_SupportType).Where(sl => sl._era_task_value == t.era_taskid).GetAllPagesAsync(ct1)).ToList();
t.era_era_task_era_selfservesupportlimits_Task = new System.Collections.ObjectModel.Collection(selfServeSupports);
+
+ var supportLimits = (await essContext.era_supportlimits.Expand(sl => sl.era_SupportType).Where(sl => sl._era_task_value == t.era_taskid).GetAllPagesAsync(ct1)).ToList();
+ t.era_era_task_era_supportlimit_Task = new System.Collections.ObjectModel.Collection(supportLimits);
});
return tasks;
diff --git a/responders/src/API/EMBC.Responders.API/Controllers/TasksController.cs b/responders/src/API/EMBC.Responders.API/Controllers/TasksController.cs
index 1217755b8..3d6a9e913 100644
--- a/responders/src/API/EMBC.Responders.API/Controllers/TasksController.cs
+++ b/responders/src/API/EMBC.Responders.API/Controllers/TasksController.cs
@@ -45,6 +45,7 @@ public async Task> GetTask(string taskId)
if (task == null) return NotFound(taskId);
var mappedTask = mapper.Map(task);
mappedTask.Workflows = GetTaskWorkflows(task);
+ mappedTask.SupportLimits = GetTaskSupportLimits(task);
return Ok(mappedTask);
}
@@ -60,6 +61,24 @@ private static IEnumerable GetTaskWorkflows(IncidentTask incidentT
return workflows;
}
+ private static IEnumerable GetTaskSupportLimits(IncidentTask incidentTask)
+ {
+ if (incidentTask.SupportLimits == null || !incidentTask.SupportLimits.Any())
+ {
+ return Enumerable.Empty();
+ }
+
+ var supportLimits = incidentTask.SupportLimits.Select(sl => new SupportLimits
+ {
+ SupportType = sl.SupportType,
+ SupportLimitStartDate = sl.SupportLimitStartDate,
+ SupportLimitEndDate = sl.SupportLimitEndDate,
+ ExtensionAvailable = sl.ExtensionAvailable
+ });
+
+ return supportLimits;
+ }
+
[HttpGet("{taskId}/suppliers")]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status200OK)]
@@ -96,6 +115,7 @@ public class ESSTask
public string Description { get; set; }
public string Status { get; set; }
public IEnumerable Workflows { get; set; } = Array.Empty();
+ public IEnumerable SupportLimits { get; set; } = Array.Empty();
}
public class TaskWorkflow
@@ -125,7 +145,8 @@ public class TaskMapping : Profile
public TaskMapping()
{
CreateMap()
- .ForMember(d => d.Workflows, opts => opts.Ignore());
+ .ForMember(d => d.Workflows, opts => opts.Ignore())
+ .ForMember(d => d.SupportLimits, opts => opts.MapFrom(s => s.SupportLimits));
CreateMap();
}
}
diff --git a/responders/src/UI/embc-responder/src/app/core/api/models/ess-task.ts b/responders/src/UI/embc-responder/src/app/core/api/models/ess-task.ts
index f7ee7e4a3..b6beb7399 100644
--- a/responders/src/UI/embc-responder/src/app/core/api/models/ess-task.ts
+++ b/responders/src/UI/embc-responder/src/app/core/api/models/ess-task.ts
@@ -1,6 +1,7 @@
/* tslint:disable */
/* eslint-disable */
import { TaskWorkflow } from '../models/task-workflow';
+import { SupportLimit } from './support-limit';
export interface EssTask {
communityCode?: string | null;
description?: string | null;
@@ -9,4 +10,5 @@ export interface EssTask {
startDate?: string;
status?: string | null;
workflows?: Array | null;
+ supportLimits?: Array | null;
}
diff --git a/responders/src/UI/embc-responder/src/app/core/api/models/support-limit.ts b/responders/src/UI/embc-responder/src/app/core/api/models/support-limit.ts
new file mode 100644
index 000000000..5cebd3e6d
--- /dev/null
+++ b/responders/src/UI/embc-responder/src/app/core/api/models/support-limit.ts
@@ -0,0 +1,9 @@
+/* tslint:disable */
+/* eslint-disable */
+import { SupportSubCategory } from './support-sub-category';
+export interface SupportLimit {
+ supportLimitStartDate: Date;
+ supportLimitEndDate: Date;
+ extensionAvailable: boolean;
+ supportType: SupportSubCategory
+}
diff --git a/responders/src/UI/embc-responder/src/app/feature-components/wizard/step-supports/step-supports.service.ts b/responders/src/UI/embc-responder/src/app/feature-components/wizard/step-supports/step-supports.service.ts
index 18a0dc8fe..72a59e594 100644
--- a/responders/src/UI/embc-responder/src/app/feature-components/wizard/step-supports/step-supports.service.ts
+++ b/responders/src/UI/embc-responder/src/app/feature-components/wizard/step-supports/step-supports.service.ts
@@ -31,6 +31,7 @@ import { DateConversionService } from 'src/app/core/services/utility/dateConvers
import { ComputeRulesService } from 'src/app/core/services/computeRules.service';
import { AppBaseService } from 'src/app/core/services/helper/appBase.service';
import { EvacueeSessionService } from 'src/app/core/services/evacuee-session.service';
+import { SupportLimit } from 'src/app/core/api/models/support-limit';
@Injectable({ providedIn: 'root' })
export class StepSupportsService {
@@ -41,6 +42,8 @@ export class StepSupportsService {
private supportDetailsVal: SupportDetailsModel;
private supportDeliveryVal: SupportDeliveryModel;
private selectedSupportDetailVal: Support;
+ private supportLimitsVal: BehaviorSubject = new BehaviorSubject([]);
+ private supportLimitsVal$: Observable = this.supportLimitsVal.asObservable();
constructor(
private essFileService: EssFileService,
@@ -89,6 +92,36 @@ export class StepSupportsService {
return this.existingSupportListVal$;
}
+ setStoredSupportLimits(supportLimits: SupportLimit[]): void {
+ this.supportLimitsVal.next(supportLimits);
+ }
+
+ getStoredSupportLimits(): Observable {
+ return this.supportLimitsVal$;
+ }
+
+ fetchSupportLimits(): Observable {
+ return this.taskService
+ .tasksGetTask({
+ taskId: this.userService?.currentProfile?.taskNumber
+ })
+ .pipe(
+ map((task) => {
+ const supportLimits: SupportLimit[] = task.supportLimits.map((supportLimit) => {
+ return {
+ supportLimitStartDate: supportLimit.supportLimitStartDate,
+ supportLimitEndDate: supportLimit.supportLimitEndDate,
+ extensionAvailable: supportLimit.extensionAvailable,
+ supportType: supportLimit.supportType
+ };
+ });
+
+ this.setStoredSupportLimits(supportLimits);
+ return supportLimits;
+ })
+ );
+ }
+
set supportTypeToAdd(supportTypeToAddVal: Code) {
this.supportTypeToAddVal = supportTypeToAddVal;
this.cacheService.set('supportType', JSON.stringify(supportTypeToAddVal));
diff --git a/responders/src/UI/embc-responder/src/app/feature-components/wizard/support-components/support-details/support-details.component.html b/responders/src/UI/embc-responder/src/app/feature-components/wizard/support-components/support-details/support-details.component.html
index 51717bcf0..c968abcf2 100644
--- a/responders/src/UI/embc-responder/src/app/feature-components/wizard/support-components/support-details/support-details.component.html
+++ b/responders/src/UI/embc-responder/src/app/feature-components/wizard/support-components/support-details/support-details.component.html
@@ -377,38 +377,50 @@
-
-
-
- All household members
-
+
- @for (member of evacueeSessionService?.evacFile?.needsAssessment?.householdMembers; track member) {
+
- {{ member.lastName | uppercase }}, {{ member.firstName | titlecase }}All household members
- }
- @if (
- supportDetailsFormControl.members.invalid &&
- supportDetailsFormControl.members.hasError('noSelection')
- ) {
-
Required
- }
-
+ @for (member of evacueeSessionService?.evacFile?.needsAssessment?.householdMembers; track member) {
+
+
+
+ {{ member.lastName | uppercase }}, {{ member.firstName | titlecase }}
+
+
+ @if (!isHouseholdMemberEligibleForSupport(member)) {
+
+ {{ member.firstName | titlecase }} {{ member.lastName | titlecase }} has already received
+ this support. Extensions for this support are not available at this time.
+
+ }
+
+
+ }
+ @if (
+ supportDetailsFormControl.members.invalid &&
+ supportDetailsFormControl.members.hasError('noSelection')
+ ) {
+
Required
+ }
+
@switch (stepSupportsService?.supportTypeToAdd?.value) {
diff --git a/responders/src/UI/embc-responder/src/app/feature-components/wizard/support-components/support-details/support-details.component.ts b/responders/src/UI/embc-responder/src/app/feature-components/wizard/support-components/support-details/support-details.component.ts
index 08f44b828..0df027385 100644
--- a/responders/src/UI/embc-responder/src/app/feature-components/wizard/support-components/support-details/support-details.component.ts
+++ b/responders/src/UI/embc-responder/src/app/feature-components/wizard/support-components/support-details/support-details.component.ts
@@ -1,5 +1,5 @@
-import { DatePipe, NgStyle, UpperCasePipe, TitleCasePipe } from '@angular/common';
-import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core';
+import { DatePipe, NgStyle, UpperCasePipe, TitleCasePipe, CommonModule } from '@angular/common';
+import { ChangeDetectionStrategy, Component, OnDestroy, OnInit, ChangeDetectorRef } from '@angular/core';
import {
AbstractControl,
UntypedFormArray,
@@ -54,6 +54,7 @@ import { AppLoaderComponent } from '../../../../shared/components/app-loader/app
import { MatInput } from '@angular/material/input';
import { MatFormField, MatPrefix, MatError, MatLabel, MatSuffix } from '@angular/material/form-field';
import { MatCard, MatCardContent } from '@angular/material/card';
+import { MatTooltipModule } from '@angular/material/tooltip';
@Component({
selector: 'app-support-details',
@@ -80,6 +81,7 @@ import { MatCard, MatCardContent } from '@angular/material/card';
MatSelect,
MatOption,
MatCheckbox,
+ MatTooltipModule,
ShelterAllowanceGroupComponent,
FoodMealsComponent,
FoodGroceriesComponent,
@@ -93,7 +95,8 @@ import { MatCard, MatCardContent } from '@angular/material/card';
MatButton,
UpperCasePipe,
TitleCasePipe,
- DatePipe
+ DatePipe,
+ CommonModule
]
})
export class SupportDetailsComponent implements OnInit, OnDestroy {
@@ -112,6 +115,8 @@ export class SupportDetailsComponent implements OnInit, OnDestroy {
originalSupport: Support;
existingSupports: Support[];
supportListSubscription: Subscription;
+ supportLimits: any;
+ supportLimitsSubscription: Subscription;
constructor(
private router: Router,
@@ -126,6 +131,7 @@ export class SupportDetailsComponent implements OnInit, OnDestroy {
private referralCreationService: ReferralCreationService,
private dateConversionService: DateConversionService,
private computeState: ComputeRulesService,
+ private cdr: ChangeDetectorRef,
private loadEvacueeListService: LoadEvacueeListService
) {
if (this.router.getCurrentNavigation() !== null) {
@@ -235,6 +241,22 @@ export class SupportDetailsComponent implements OnInit, OnDestroy {
};
ngOnInit(): void {
+ this.showLoader = true;
+ this.supportLimitsSubscription = this.stepSupportsService.fetchSupportLimits().subscribe({
+ next: (supportLimits) => {
+ this.supportLimits = supportLimits;
+ this.showLoader = false;
+ this.cdr.detectChanges();
+ },
+ error: (error) => {
+ this.showLoader = false;
+ console.error('Error fetching support limits: ', error);
+ this.alertService.clearAlert();
+ this.alertService.setAlert('danger', globalConst.supportListerror);
+ this.cdr.detectChanges();
+ }
+ });
+
this.supportListSubscription = this.stepSupportsService.getExistingSupportList().subscribe({
next: (supports) => {
this.existingSupports = supports;
@@ -277,6 +299,42 @@ export class SupportDetailsComponent implements OnInit, OnDestroy {
ngOnDestroy(): void {
this.supportListSubscription.unsubscribe();
+ this.supportLimitsSubscription.unsubscribe();
+ }
+
+ isHouseholdMemberEligibleForSupport(member: EvacuationFileHouseholdMember): boolean {
+ if (!this.supportLimits || this.supportLimits.length === 0) {
+ return true;
+ }
+ const currentSupportType = this.stepSupportsService.supportTypeToAdd.description;
+ const matchingSupportLimit = this.supportLimits.find(
+ (limit) => this.mapSupportType(limit.supportType) === currentSupportType
+ );
+ if (!matchingSupportLimit) {
+ return true;
+ }
+ if (matchingSupportLimit.extensionAvailable) {
+ return true;
+ }
+ const supportLimitStartDate = moment(matchingSupportLimit.supportLimitStartDate);
+ const supportLimitEndDate = moment(matchingSupportLimit.supportLimitEndDate);
+ const hasReceivedSupport = this.existingSupports.some((support) => {
+ const supportDate = moment(support.from);
+ return (
+ support.category === currentSupportType &&
+ support.includedHouseholdMembers?.some((m) => m === member.id) &&
+ support.status !== SupportStatus.Cancelled.toString() &&
+ support.status !== SupportStatus.Void.toString() &&
+ supportDate.isBetween(supportLimitStartDate, supportLimitEndDate, 'days', '[]')
+ );
+ });
+ return !hasReceivedSupport;
+ }
+
+ allMembersEligible(): boolean {
+ return this.evacueeSessionService?.evacFile?.needsAssessment?.householdMembers.every((member) =>
+ this.isHouseholdMemberEligibleForSupport(member)
+ );
}
checkDateRange(): boolean {
@@ -378,7 +436,9 @@ export class SupportDetailsComponent implements OnInit, OnDestroy {
if ($event.checked) {
members.clear();
this.evacueeSessionService?.evacFile?.needsAssessment?.householdMembers.forEach((member) => {
- members.push(new UntypedFormControl(member));
+ if (this.isHouseholdMemberEligibleForSupport(member)) {
+ members.push(new UntypedFormControl(member));
+ }
});
} else {
members.clear();
@@ -687,6 +747,33 @@ export class SupportDetailsComponent implements OnInit, OnDestroy {
return largestToTime;
}
+ private mapSupportType(supportType: number): SupportSubCategory | SupportCategory {
+ switch (supportType) {
+ case 174360000:
+ return SupportSubCategory.Food_Groceries;
+ case 174360001:
+ return SupportSubCategory.Food_Restaurant;
+ case 174360002:
+ return SupportSubCategory.Lodging_Hotel;
+ case 174360003:
+ return SupportSubCategory.Lodging_Billeting;
+ case 174360004:
+ return SupportSubCategory.Lodging_Group;
+ case 174360005:
+ return SupportCategory.Incidentals;
+ case 174360006:
+ return SupportCategory.Clothing;
+ case 174360007:
+ return SupportSubCategory.Transportation_Taxi;
+ case 174360008:
+ return SupportSubCategory.Transportation_Other;
+ case 174360009:
+ return SupportSubCategory.Lodging_Allowance;
+ default:
+ return SupportCategory.Unknown;
+ }
+ }
+
private setToTime() {
if (this.evacueeSessionService.isPaperBased) {
return this.stepSupportsService?.supportDetails?.toTime ? this.stepSupportsService?.supportDetails?.toTime : '';
diff --git a/responders/src/UI/embc-responder/src/styles/styles.scss b/responders/src/UI/embc-responder/src/styles/styles.scss
index 7634b27d1..f1e172595 100644
--- a/responders/src/UI/embc-responder/src/styles/styles.scss
+++ b/responders/src/UI/embc-responder/src/styles/styles.scss
@@ -371,6 +371,11 @@ mat-form-field {
font-size: 75%;
}
+.custom-mat-info {
+ font-size: 75%;
+ color: #000 !important;
+}
+
.mat-mdc-dialog-container {
border-radius: 0px !important;
}
diff --git a/shared/src/EMBC.ESS.Shared.Contracts/Events/Tasks.cs b/shared/src/EMBC.ESS.Shared.Contracts/Events/Tasks.cs
index 791f619bc..6f5f83c37 100644
--- a/shared/src/EMBC.ESS.Shared.Contracts/Events/Tasks.cs
+++ b/shared/src/EMBC.ESS.Shared.Contracts/Events/Tasks.cs
@@ -39,6 +39,7 @@ public class IncidentTask
public IncidentTaskStatus Status { get; set; }
public bool RemoteExtensionsEnabled { get; set; }
public bool SelfServeEnabled { get; set; }
+ public IEnumerable SupportLimits { get; set; }
}
public enum IncidentTaskStatus
@@ -46,4 +47,26 @@ public enum IncidentTaskStatus
Active,
Expired
}
+
+ public record SupportLimits
+ {
+ public SupportType SupportType { get; set; }
+ public DateTime SupportLimitStartDate { get; set; }
+ public DateTime SupportLimitEndDate { get; set; }
+ public bool ExtensionAvailable { get; set; }
+ }
+
+ public enum SupportType
+ {
+ FoodGroceries = 174360000,
+ FoodRestaurant = 174360001,
+ ShelterHotel = 174360002,
+ ShelterBilleting = 174360003,
+ ShelterGroup = 174360004,
+ Incidentals = 174360005,
+ Clothing = 174360006,
+ TransporationTaxi = 174360007,
+ TransportationOther = 174360008,
+ ShelterAllowance = 174360009
+ }
}