diff --git a/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details-enforcement-tab/fines-acc-defendant-details-enforcement-tab.component.html b/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details-enforcement-tab/fines-acc-defendant-details-enforcement-tab.component.html
index 79213afe10..dfe1fc6a01 100644
--- a/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details-enforcement-tab/fines-acc-defendant-details-enforcement-tab.component.html
+++ b/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details-enforcement-tab/fines-acc-defendant-details-enforcement-tab.component.html
@@ -68,6 +68,7 @@
Enforcement status
summaryListId="enforcementOverviewDetails"
summaryListRowId="enforcement_court"
[actionEnabled]="hasAccountMaintenancePermission ? true : false"
+ (actionClick)="handleChangeEnforcementCourt()"
>
Enforcement court
diff --git a/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details-enforcement-tab/fines-acc-defendant-details-enforcement-tab.component.spec.ts b/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details-enforcement-tab/fines-acc-defendant-details-enforcement-tab.component.spec.ts
index bcace27490..5d41d0ad94 100644
--- a/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details-enforcement-tab/fines-acc-defendant-details-enforcement-tab.component.spec.ts
+++ b/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details-enforcement-tab/fines-acc-defendant-details-enforcement-tab.component.spec.ts
@@ -31,4 +31,13 @@ describe('FinesAccDefendantDetailsEnforcementTab', () => {
expect(event.preventDefault).toHaveBeenCalled();
expect(eventEmitterSpy).toHaveBeenCalled();
});
+
+ it('should emit the current enforcement court id when handleChangeEnforcementCourt is called', () => {
+ const eventEmitterSpy = vi.spyOn(component.changeEnforcementCourt, 'emit');
+ component.hasAccountMaintenancePermission = true;
+
+ component.handleChangeEnforcementCourt();
+
+ expect(eventEmitterSpy).toHaveBeenCalledWith(123);
+ });
});
diff --git a/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details-enforcement-tab/fines-acc-defendant-details-enforcement-tab.component.ts b/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details-enforcement-tab/fines-acc-defendant-details-enforcement-tab.component.ts
index 19ec837685..8fbe51ef71 100644
--- a/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details-enforcement-tab/fines-acc-defendant-details-enforcement-tab.component.ts
+++ b/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details-enforcement-tab/fines-acc-defendant-details-enforcement-tab.component.ts
@@ -39,6 +39,7 @@ export class FinesAccDefendantDetailsEnforcementTab {
@Input() hasAccountMaintenancePermission: boolean = false;
@Input() hasEnterEnforcementPermission: boolean = false;
@Output() addEnforcementOverride = new EventEmitter();
+ @Output() changeEnforcementCourt = new EventEmitter();
/**
* Emits an event to add an enforcement override if the user has the necessary permissions and there is no existing enforcement override result.
@@ -53,4 +54,13 @@ export class FinesAccDefendantDetailsEnforcementTab {
this.addEnforcementOverride.emit();
}
}
+
+ /**
+ * Emits the current enforcement court id when the user can change it.
+ */
+ public handleChangeEnforcementCourt(): void {
+ if (this.hasAccountMaintenancePermission) {
+ this.changeEnforcementCourt.emit(this.tabData.enforcement_overview.enforcement_court?.court_id ?? null);
+ }
+ }
}
diff --git a/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details.component.html b/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details.component.html
index 39396c237f..4276da373e 100644
--- a/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details.component.html
+++ b/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details.component.html
@@ -206,6 +206,7 @@ Business Unit:
[hasAccountMaintenancePermission]="hasPermission('account-maintenance')"
[hasEnterEnforcementPermission]="hasPermission('enter-enforcement')"
(addEnforcementOverride)="navigateToAddEnforcementOverridePage()"
+ (changeEnforcementCourt)="navigateToChangeEnforcementCourtPage($event)"
>
}
}
diff --git a/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details.component.spec.ts b/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details.component.spec.ts
index feaa9c5f9b..a898a6f2a0 100644
--- a/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details.component.spec.ts
+++ b/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details.component.spec.ts
@@ -22,6 +22,7 @@ import { FINES_ACC_PARTY_ADD_AMEND_CONVERT_PARTY_TYPES } from '../fines-acc-part
import { OPAL_FINES_ACCOUNT_DEFENDANT_DETAILS_PARENT_OR_GUARDIAN_TAB_REF_DATA_MOCK } from '@services/fines/opal-fines-service/mocks/opal-fines-account-defendant-details-parent-or-guardian-tab-ref-data.mock';
import { OPAL_FINES_ACCOUNT_DEFENDANT_DETAILS_FIXED_PENALTY_MOCK } from '@services/fines/opal-fines-service/mocks/opal-fines-account-defendant-details-fixed-penalty.mock';
import { OPAL_FINES_RESULT_REF_DATA_MOCK } from '@services/fines/opal-fines-service/mocks/opal-fines-result-ref-data.mock';
+import { FINES_ACC_ENF_COURT_CHANGE_ROUTING_PATHS } from '../fines-acc-enf-court-change/constants/fines-acc-enf-court-change-routing-paths.constant';
import { beforeEach, describe, expect, it, vi } from 'vitest';
describe('FinesAccDefendantDetailsComponent', () => {
@@ -168,6 +169,20 @@ describe('FinesAccDefendantDetailsComponent', () => {
);
});
+ it('should call router.navigate when navigateToChangeEnforcementCourtPage is called', () => {
+ component.navigateToChangeEnforcementCourtPage(123);
+
+ expect(routerSpy.navigate).toHaveBeenCalledWith(
+ [
+ `../${FINES_ACC_DEFENDANT_ROUTING_PATHS.children.enforcement}/${FINES_ACC_ENF_COURT_CHANGE_ROUTING_PATHS.root}/${FINES_ACC_ENF_COURT_CHANGE_ROUTING_PATHS.children.change}`,
+ ],
+ {
+ relativeTo: component['activatedRoute'],
+ state: { currentEnforcementCourtId: 123 },
+ },
+ );
+ });
+
it('should fetch the defendant tab data when fragment is changed to defendant', () => {
component['refreshFragment$'].next('defendant');
// Subscribe to trigger the pipe execution
diff --git a/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details.component.ts b/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details.component.ts
index c8d7f1b673..8e914f5bed 100644
--- a/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details.component.ts
+++ b/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details.component.ts
@@ -55,6 +55,7 @@ import { FINES_ACCOUNT_TYPES } from '../../constants/fines-account-types.constan
import { IOpalFinesResultRefData } from '@services/fines/opal-fines-service/interfaces/opal-fines-result-ref-data.interface';
import { FinesAccDefendantDetailsEnforcementTab } from './fines-acc-defendant-details-enforcement-tab/fines-acc-defendant-details-enforcement-tab.component';
import { FinesAccSummaryHeaderComponent } from '../fines-acc-summary-header/fines-acc-summary-header.component';
+import { FINES_ACC_ENF_COURT_CHANGE_ROUTING_PATHS } from '../fines-acc-enf-court-change/constants/fines-acc-enf-court-change-routing-paths.constant';
@Component({
selector: 'app-fines-acc-defendant-details',
@@ -458,4 +459,21 @@ export class FinesAccDefendantDetailsComponent extends AbstractTabData implement
relativeTo: this.activatedRoute,
});
}
+
+ /**
+ * Navigates to the change enforcement court page, preserving the current court id for no-op submissions.
+ *
+ * @param currentEnforcementCourtId The current enforcement court id shown on the enforcement tab.
+ */
+ public navigateToChangeEnforcementCourtPage(currentEnforcementCourtId: number | null): void {
+ this['router'].navigate(
+ [
+ `../${FINES_ACC_DEFENDANT_ROUTING_PATHS.children.enforcement}/${FINES_ACC_ENF_COURT_CHANGE_ROUTING_PATHS.root}/${FINES_ACC_ENF_COURT_CHANGE_ROUTING_PATHS.children.change}`,
+ ],
+ {
+ relativeTo: this.activatedRoute,
+ state: { currentEnforcementCourtId },
+ },
+ );
+ }
}
diff --git a/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/constants/fines-acc-enf-court-change-field-errors.constant.ts b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/constants/fines-acc-enf-court-change-field-errors.constant.ts
new file mode 100644
index 0000000000..2e90730c20
--- /dev/null
+++ b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/constants/fines-acc-enf-court-change-field-errors.constant.ts
@@ -0,0 +1,10 @@
+import { IFinesAccEnfCourtChangeFieldErrors } from '../interfaces/fines-acc-enf-court-change-field-errors.interface';
+
+export const FINES_ACC_ENF_COURT_CHANGE_FIELD_ERRORS: IFinesAccEnfCourtChangeFieldErrors = {
+ facc_enf_court: {
+ required: {
+ message: 'Select an enforcement court',
+ priority: 1,
+ },
+ },
+};
diff --git a/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/constants/fines-acc-enf-court-change-routing-paths.constant.ts b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/constants/fines-acc-enf-court-change-routing-paths.constant.ts
new file mode 100644
index 0000000000..d595f01f1e
--- /dev/null
+++ b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/constants/fines-acc-enf-court-change-routing-paths.constant.ts
@@ -0,0 +1,8 @@
+import { IFinesAccEnfCourtChangeRoutingPaths } from '../interfaces/fines-acc-enf-court-change-routing-paths.interface';
+
+export const FINES_ACC_ENF_COURT_CHANGE_ROUTING_PATHS: IFinesAccEnfCourtChangeRoutingPaths = {
+ root: 'court',
+ children: {
+ change: 'change',
+ },
+};
diff --git a/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/constants/fines-acc-enf-court-change-routing-titles.constant.ts b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/constants/fines-acc-enf-court-change-routing-titles.constant.ts
new file mode 100644
index 0000000000..2f7c2105fb
--- /dev/null
+++ b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/constants/fines-acc-enf-court-change-routing-titles.constant.ts
@@ -0,0 +1,8 @@
+import { IFinesAccEnfCourtChangeRoutingPaths } from '../interfaces/fines-acc-enf-court-change-routing-paths.interface';
+
+export const FINES_ACC_ENF_COURT_CHANGE_ROUTING_TITLES: IFinesAccEnfCourtChangeRoutingPaths = {
+ root: 'Enforcement court',
+ children: {
+ change: 'Change enforcement court',
+ },
+};
diff --git a/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/constants/fines-acc-enf-court-change-success-message.constant.ts b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/constants/fines-acc-enf-court-change-success-message.constant.ts
new file mode 100644
index 0000000000..e93a6276a5
--- /dev/null
+++ b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/constants/fines-acc-enf-court-change-success-message.constant.ts
@@ -0,0 +1 @@
+export const FINES_ACC_ENF_COURT_CHANGE_SUCCESS_MESSAGE = 'Enforcement court changed';
diff --git a/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/fines-acc-enf-court-change-form/fines-acc-enf-court-change-form.component.html b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/fines-acc-enf-court-change-form/fines-acc-enf-court-change-form.component.html
new file mode 100644
index 0000000000..295d26c703
--- /dev/null
+++ b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/fines-acc-enf-court-change-form/fines-acc-enf-court-change-form.component.html
@@ -0,0 +1,30 @@
+
+
+
+
diff --git a/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/fines-acc-enf-court-change-form/fines-acc-enf-court-change-form.component.spec.ts b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/fines-acc-enf-court-change-form/fines-acc-enf-court-change-form.component.spec.ts
new file mode 100644
index 0000000000..d27c691ee2
--- /dev/null
+++ b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/fines-acc-enf-court-change-form/fines-acc-enf-court-change-form.component.spec.ts
@@ -0,0 +1,42 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ActivatedRoute } from '@angular/router';
+import { beforeEach, describe, expect, it, vi } from 'vitest';
+import { FinesAccEnfCourtChangeFormComponent } from './fines-acc-enf-court-change-form.component';
+
+describe('FinesAccEnfCourtChangeFormComponent', () => {
+ let component: FinesAccEnfCourtChangeFormComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [FinesAccEnfCourtChangeFormComponent],
+ providers: [{ provide: ActivatedRoute, useValue: { snapshot: { params: {}, data: {} } } }],
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(FinesAccEnfCourtChangeFormComponent);
+ component = fixture.componentInstance;
+ component.accountNumber = '123456';
+ component.courtOptions = [{ value: 101, name: 'Test Court (101)' }];
+ component.partyName = 'Mr Test PERSON';
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should initialize the enforcement court control as required', () => {
+ const control = component.form.get('facc_enf_court');
+
+ expect(control).toBeTruthy();
+ expect(control?.hasError('required')).toBe(true);
+ });
+
+ it('should emit cancel when handleCancel is called', () => {
+ const emitSpy = vi.spyOn(component.cancelRequested, 'emit');
+
+ component.handleCancel();
+
+ expect(emitSpy).toHaveBeenCalled();
+ });
+});
diff --git a/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/fines-acc-enf-court-change-form/fines-acc-enf-court-change-form.component.ts b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/fines-acc-enf-court-change-form/fines-acc-enf-court-change-form.component.ts
new file mode 100644
index 0000000000..dca3d219a2
--- /dev/null
+++ b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/fines-acc-enf-court-change-form/fines-acc-enf-court-change-form.component.ts
@@ -0,0 +1,67 @@
+import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
+import { FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
+import { AbstractFormBaseComponent } from '@hmcts/opal-frontend-common/components/abstract/abstract-form-base';
+import {
+ IAbstractFormBaseFieldErrors,
+ IAbstractFormBaseForm,
+} from '@hmcts/opal-frontend-common/components/abstract/abstract-form-base/interfaces';
+import { IAbstractFormControlErrorMessage } from '@hmcts/opal-frontend-common/components/abstract/interfaces';
+import { AlphagovAccessibleAutocompleteComponent } from '@hmcts/opal-frontend-common/components/alphagov/alphagov-accessible-autocomplete';
+import { IAlphagovAccessibleAutocompleteItem } from '@hmcts/opal-frontend-common/components/alphagov/alphagov-accessible-autocomplete/interfaces';
+import { GovukButtonComponent } from '@hmcts/opal-frontend-common/components/govuk/govuk-button';
+import { GovukCancelLinkComponent } from '@hmcts/opal-frontend-common/components/govuk/govuk-cancel-link';
+import { GovukErrorSummaryComponent } from '@hmcts/opal-frontend-common/components/govuk/govuk-error-summary';
+import { GovukHeadingWithCaptionComponent } from '@hmcts/opal-frontend-common/components/govuk/govuk-heading-with-caption';
+import { FINES_ACC_ENF_COURT_CHANGE_FIELD_ERRORS } from '../constants/fines-acc-enf-court-change-field-errors.constant';
+import { IFinesAccEnfCourtChangeFormState } from '../interfaces/fines-acc-enf-court-change-form-state.interface';
+
+@Component({
+ selector: 'app-fines-acc-enf-court-change-form',
+ imports: [
+ FormsModule,
+ ReactiveFormsModule,
+ AlphagovAccessibleAutocompleteComponent,
+ GovukButtonComponent,
+ GovukCancelLinkComponent,
+ GovukErrorSummaryComponent,
+ GovukHeadingWithCaptionComponent,
+ ],
+ templateUrl: './fines-acc-enf-court-change-form.component.html',
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ standalone: true,
+})
+export class FinesAccEnfCourtChangeFormComponent extends AbstractFormBaseComponent implements OnInit, OnDestroy {
+ protected override fieldErrors: IAbstractFormBaseFieldErrors = {
+ ...FINES_ACC_ENF_COURT_CHANGE_FIELD_ERRORS,
+ };
+ protected override formSubmit = new EventEmitter>();
+ @Output() public cancelRequested = new EventEmitter();
+ public override formControlErrorMessages: IAbstractFormControlErrorMessage = {};
+ @Input({ required: true }) public accountNumber!: string;
+ @Input({ required: true }) public courtOptions!: IAlphagovAccessibleAutocompleteItem[];
+ @Input({ required: true }) public partyName!: string;
+
+ /**
+ * Sets up the enforcement court change form with the required court control.
+ */
+ private setupForm(): void {
+ this.form = new FormGroup({
+ facc_enf_court: new FormControl(null, Validators.required),
+ });
+ }
+
+ /**
+ * Initializes the form before wiring up the shared form behaviour.
+ */
+ public override ngOnInit(): void {
+ this.setupForm();
+ super.ngOnInit();
+ }
+
+ /**
+ * Emits the cancel action to the parent component.
+ */
+ public handleCancel(): void {
+ this.cancelRequested.emit();
+ }
+}
diff --git a/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/fines-acc-enf-court-change.component.html b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/fines-acc-enf-court-change.component.html
new file mode 100644
index 0000000000..d53d3eb3db
--- /dev/null
+++ b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/fines-acc-enf-court-change.component.html
@@ -0,0 +1,10 @@
+
diff --git a/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/fines-acc-enf-court-change.component.spec.ts b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/fines-acc-enf-court-change.component.spec.ts
new file mode 100644
index 0000000000..e3be5fe3ef
--- /dev/null
+++ b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/fines-acc-enf-court-change.component.spec.ts
@@ -0,0 +1,205 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { signal, WritableSignal } from '@angular/core';
+import { ActivatedRoute, Navigation, Router } from '@angular/router';
+import { beforeEach, describe, expect, it, vi } from 'vitest';
+import { of, throwError } from 'rxjs';
+import { FinesAccEnfCourtChangeComponent } from './fines-acc-enf-court-change.component';
+import { FinesAccountStore } from '../stores/fines-acc.store';
+import { FinesAccPayloadService } from '../services/fines-acc-payload.service';
+import { OpalFines } from '@services/fines/opal-fines-service/opal-fines.service';
+import { UtilsService } from '@hmcts/opal-frontend-common/services/utils-service';
+import { FINES_ACC_DEFENDANT_ROUTING_PATHS } from '../routing/constants/fines-acc-defendant-routing-paths.constant';
+import { FINES_ACC_ENF_COURT_CHANGE_SUCCESS_MESSAGE } from './constants/fines-acc-enf-court-change-success-message.constant';
+import { OPAL_FINES_COURT_REF_DATA_MOCK } from '@services/fines/opal-fines-service/mocks/opal-fines-court-ref-data.mock';
+
+describe('FinesAccEnfCourtChangeComponent', () => {
+ let component: FinesAccEnfCourtChangeComponent;
+ let fixture: ComponentFixture;
+ let mockCurrentNavigation: WritableSignal;
+ const mockCourtRefData = structuredClone(OPAL_FINES_COURT_REF_DATA_MOCK);
+ const selectedCourt = mockCourtRefData.refData[1];
+ const currentCourt = mockCourtRefData.refData[0];
+
+ const mockAccountStore = {
+ getAccountNumber: signal('123456'),
+ party_name: signal('Mr Test PERSON'),
+ account_id: signal(1001),
+ base_version: signal('1'),
+ business_unit_id: signal('2002'),
+ setSuccessMessage: vi.fn(),
+ };
+
+ const mockPayloadService = {
+ buildEnforcementCourtFormPayload: vi
+ .fn()
+ .mockReturnValue({ enforcement_court: { court_id: selectedCourt.court_id } }),
+ };
+
+ const mockOpalFinesService = {
+ patchDefendantAccount: vi.fn().mockReturnValue(of({})),
+ getCourtPrettyName: vi.fn(
+ (court: { name: string; court_code: string | number }) => `${court.name} (${court.court_code})`,
+ ),
+ };
+
+ const mockUtilsService = {
+ scrollToTop: vi.fn(),
+ };
+
+ beforeEach(async () => {
+ vi.clearAllMocks();
+
+ mockCurrentNavigation = signal({
+ extras: {
+ state: {},
+ },
+ } as unknown as Navigation);
+
+ await TestBed.configureTestingModule({
+ imports: [FinesAccEnfCourtChangeComponent],
+ providers: [
+ {
+ provide: ActivatedRoute,
+ useValue: {
+ snapshot: {
+ data: {
+ courtsRefData: mockCourtRefData,
+ },
+ },
+ },
+ },
+ {
+ provide: Router,
+ useValue: {
+ currentNavigation: mockCurrentNavigation,
+ navigate: vi.fn(),
+ },
+ },
+ { provide: FinesAccountStore, useValue: mockAccountStore },
+ { provide: FinesAccPayloadService, useValue: mockPayloadService },
+ { provide: OpalFines, useValue: mockOpalFinesService },
+ { provide: UtilsService, useValue: mockUtilsService },
+ ],
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(FinesAccEnfCourtChangeComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should map route data into autocomplete options', () => {
+ expect(component.courtOptions).toEqual(
+ mockCourtRefData.refData.map((court) => ({
+ value: court.court_id,
+ name: `${court.name} (${court.court_code})`,
+ })),
+ );
+ });
+
+ it('should patch and navigate on success when the selected court changes', () => {
+ const routerNavigateSpy = vi.spyOn(component as never, 'routerNavigate');
+
+ component.handleSubmit({
+ formData: {
+ facc_enf_court: selectedCourt.court_id,
+ },
+ nestedFlow: false,
+ });
+
+ expect(mockPayloadService.buildEnforcementCourtFormPayload).toHaveBeenCalledWith({
+ facc_enf_court: selectedCourt.court_id,
+ });
+ expect(mockOpalFinesService.patchDefendantAccount).toHaveBeenCalledWith(
+ 1001,
+ { enforcement_court: { court_id: selectedCourt.court_id } },
+ '1',
+ '2002',
+ );
+ expect(mockAccountStore.setSuccessMessage).toHaveBeenCalledWith(FINES_ACC_ENF_COURT_CHANGE_SUCCESS_MESSAGE);
+ expect(routerNavigateSpy).toHaveBeenCalledWith(
+ FINES_ACC_DEFENDANT_ROUTING_PATHS.children.details,
+ false,
+ undefined,
+ null,
+ 'enforcement',
+ );
+ });
+
+ it('should navigate back without patching when the selected court matches the current court', () => {
+ mockCurrentNavigation.set({
+ extras: {
+ state: {
+ currentEnforcementCourtId: currentCourt.court_id,
+ },
+ },
+ } as unknown as Navigation);
+
+ fixture = TestBed.createComponent(FinesAccEnfCourtChangeComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+
+ const routerNavigateSpy = vi.spyOn(component as never, 'routerNavigate');
+
+ component.handleSubmit({
+ formData: {
+ facc_enf_court: currentCourt.court_id,
+ },
+ nestedFlow: false,
+ });
+
+ expect(mockPayloadService.buildEnforcementCourtFormPayload).not.toHaveBeenCalled();
+ expect(mockOpalFinesService.patchDefendantAccount).not.toHaveBeenCalled();
+ expect(mockAccountStore.setSuccessMessage).not.toHaveBeenCalled();
+ expect(routerNavigateSpy).toHaveBeenCalledWith(
+ FINES_ACC_DEFENDANT_ROUTING_PATHS.children.details,
+ false,
+ undefined,
+ null,
+ 'enforcement',
+ );
+ });
+
+ it('should scroll to top on submit error', () => {
+ mockOpalFinesService.patchDefendantAccount = vi.fn().mockReturnValue(throwError(() => new Error('fail')));
+ fixture = TestBed.createComponent(FinesAccEnfCourtChangeComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+
+ const routerNavigateSpy = vi.spyOn(component as never, 'routerNavigate');
+
+ component.handleSubmit({
+ formData: {
+ facc_enf_court: selectedCourt.court_id,
+ },
+ nestedFlow: false,
+ });
+
+ expect(mockUtilsService.scrollToTop).toHaveBeenCalled();
+ expect(routerNavigateSpy).not.toHaveBeenCalled();
+ });
+
+ it('should update stateUnsavedChanges when handleUnsavedChanges is called', () => {
+ component.handleUnsavedChanges(true);
+
+ expect((component as unknown as { stateUnsavedChanges: boolean }).stateUnsavedChanges).toBe(true);
+ });
+
+ it('should navigate back to the enforcement tab when cancel is triggered', () => {
+ const routerNavigateSpy = vi.spyOn(component as never, 'routerNavigate');
+
+ component.handleCancel();
+
+ expect(mockAccountStore.setSuccessMessage).not.toHaveBeenCalled();
+ expect(routerNavigateSpy).toHaveBeenCalledWith(
+ FINES_ACC_DEFENDANT_ROUTING_PATHS.children.details,
+ false,
+ undefined,
+ null,
+ 'enforcement',
+ );
+ });
+});
diff --git a/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/fines-acc-enf-court-change.component.ts b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/fines-acc-enf-court-change.component.ts
new file mode 100644
index 0000000000..edfc37dea5
--- /dev/null
+++ b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/fines-acc-enf-court-change.component.ts
@@ -0,0 +1,121 @@
+import { ChangeDetectionStrategy, Component, inject, OnDestroy } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+import { catchError, EMPTY, Subject, takeUntil } from 'rxjs';
+import { AbstractFormParentBaseComponent } from '@hmcts/opal-frontend-common/components/abstract/abstract-form-parent-base';
+import { IAbstractFormBaseForm } from '@hmcts/opal-frontend-common/components/abstract/abstract-form-base/interfaces';
+import { IAlphagovAccessibleAutocompleteItem } from '@hmcts/opal-frontend-common/components/alphagov/alphagov-accessible-autocomplete/interfaces';
+import { UtilsService } from '@hmcts/opal-frontend-common/services/utils-service';
+import { FinesAccEnfCourtChangeFormComponent } from './fines-acc-enf-court-change-form/fines-acc-enf-court-change-form.component';
+import { FinesAccountStore } from '../stores/fines-acc.store';
+import { FinesAccPayloadService } from '../services/fines-acc-payload.service';
+import { FINES_ACC_ENF_COURT_CHANGE_SUCCESS_MESSAGE } from './constants/fines-acc-enf-court-change-success-message.constant';
+import { FINES_ACC_DEFENDANT_ROUTING_PATHS } from '../routing/constants/fines-acc-defendant-routing-paths.constant';
+import { IFinesAccEnfCourtChangeFormState } from './interfaces/fines-acc-enf-court-change-form-state.interface';
+import { IOpalFinesCourtRefData } from '@services/fines/opal-fines-service/interfaces/opal-fines-court-ref-data.interface';
+import { OpalFines } from '@services/fines/opal-fines-service/opal-fines.service';
+
+@Component({
+ selector: 'app-fines-acc-enf-court-change',
+ templateUrl: './fines-acc-enf-court-change.component.html',
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ standalone: true,
+ imports: [FinesAccEnfCourtChangeFormComponent],
+})
+export class FinesAccEnfCourtChangeComponent extends AbstractFormParentBaseComponent implements OnDestroy {
+ private readonly ngUnsubscribe = new Subject();
+ private readonly route = inject(ActivatedRoute);
+ private readonly navigationRouter = inject(Router);
+ private readonly finesAccStore = inject(FinesAccountStore);
+ private readonly finesAccPayloadService = inject(FinesAccPayloadService);
+ private readonly opalFinesService = inject(OpalFines);
+ private readonly utilsService = inject(UtilsService);
+ private readonly currentEnforcementCourtId = this.navigationRouter.currentNavigation()?.extras.state?.[
+ 'currentEnforcementCourtId'
+ ] as number | null | undefined;
+
+ public accountNumber = this.finesAccStore.getAccountNumber() ?? '';
+ public partyName = this.finesAccStore.party_name() ?? '';
+ public courtOptions: IAlphagovAccessibleAutocompleteItem[] = this.setCourtOptions();
+
+ /**
+ * Maps the resolved courts reference data into autocomplete options.
+ *
+ * @returns The list of courts formatted for the autocomplete component.
+ */
+ private setCourtOptions(): IAlphagovAccessibleAutocompleteItem[] {
+ return (this.route.snapshot.data['courtsRefData'] as IOpalFinesCourtRefData).refData.map((court) => ({
+ value: court.court_id,
+ name: this.opalFinesService.getCourtPrettyName(court),
+ }));
+ }
+
+ /**
+ * Navigates back to the enforcement tab and optionally sets the success banner.
+ *
+ * @param setSuccessMessage Whether to set the success banner before navigating away.
+ */
+ private navigateToEnforcementTab(setSuccessMessage: boolean): void {
+ this.stateUnsavedChanges = false;
+
+ if (setSuccessMessage) {
+ this.finesAccStore.setSuccessMessage(FINES_ACC_ENF_COURT_CHANGE_SUCCESS_MESSAGE);
+ }
+
+ this.routerNavigate(FINES_ACC_DEFENDANT_ROUTING_PATHS.children.details, false, undefined, null, 'enforcement');
+ }
+
+ /**
+ * Submits the selected enforcement court unless it matches the current value.
+ *
+ * @param form The submitted form containing the selected enforcement court.
+ */
+ public handleSubmit(form: IAbstractFormBaseForm): void {
+ const selectedCourtId = Number(form.formData.facc_enf_court);
+
+ if (selectedCourtId === this.currentEnforcementCourtId) {
+ this.navigateToEnforcementTab(false);
+ return;
+ }
+
+ const payload = this.finesAccPayloadService.buildEnforcementCourtFormPayload(form.formData);
+ this.opalFinesService
+ .patchDefendantAccount(
+ this.finesAccStore.account_id()!,
+ payload,
+ this.finesAccStore.base_version()!,
+ this.finesAccStore.business_unit_id()!,
+ )
+ .pipe(
+ catchError(() => {
+ this.utilsService.scrollToTop();
+ return EMPTY;
+ }),
+ takeUntil(this.ngUnsubscribe),
+ )
+ .subscribe(() => this.navigateToEnforcementTab(true));
+ }
+
+ /**
+ * Navigates back to the enforcement tab without saving changes.
+ */
+ public handleCancel(): void {
+ this.navigateToEnforcementTab(false);
+ }
+
+ /**
+ * Updates the page-level unsaved changes state from the child form.
+ *
+ * @param unsavedChanges Whether the form currently has unsaved changes.
+ */
+ public handleUnsavedChanges(unsavedChanges: boolean): void {
+ this.stateUnsavedChanges = unsavedChanges;
+ }
+
+ /**
+ * Completes the destroy notifier used by active subscriptions.
+ */
+ public ngOnDestroy(): void {
+ this.ngUnsubscribe.next();
+ this.ngUnsubscribe.complete();
+ }
+}
diff --git a/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/interfaces/fines-acc-enf-court-change-field-errors.interface.ts b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/interfaces/fines-acc-enf-court-change-field-errors.interface.ts
new file mode 100644
index 0000000000..77ef795e0b
--- /dev/null
+++ b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/interfaces/fines-acc-enf-court-change-field-errors.interface.ts
@@ -0,0 +1,9 @@
+import {
+ IAbstractFormBaseFieldError,
+ IAbstractFormBaseFieldErrors,
+} from '@hmcts/opal-frontend-common/components/abstract/abstract-form-base/interfaces';
+import { IFinesAccEnfCourtChangeFormState } from './fines-acc-enf-court-change-form-state.interface';
+
+export type IFinesAccEnfCourtChangeFieldErrors = IAbstractFormBaseFieldErrors & {
+ [K in keyof IFinesAccEnfCourtChangeFormState]: IAbstractFormBaseFieldError;
+};
diff --git a/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/interfaces/fines-acc-enf-court-change-form-state.interface.ts b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/interfaces/fines-acc-enf-court-change-form-state.interface.ts
new file mode 100644
index 0000000000..4eac2c32ed
--- /dev/null
+++ b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/interfaces/fines-acc-enf-court-change-form-state.interface.ts
@@ -0,0 +1,3 @@
+export interface IFinesAccEnfCourtChangeFormState {
+ facc_enf_court: number | null;
+}
diff --git a/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/interfaces/fines-acc-enf-court-change-form.interface.ts b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/interfaces/fines-acc-enf-court-change-form.interface.ts
new file mode 100644
index 0000000000..e5a4b1bb57
--- /dev/null
+++ b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/interfaces/fines-acc-enf-court-change-form.interface.ts
@@ -0,0 +1,4 @@
+import { IAbstractFormBaseForm } from '@hmcts/opal-frontend-common/components/abstract/abstract-form-base/interfaces';
+import { IFinesAccEnfCourtChangeFormState } from './fines-acc-enf-court-change-form-state.interface';
+
+export type IFinesAccEnfCourtChangeForm = IAbstractFormBaseForm;
diff --git a/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/interfaces/fines-acc-enf-court-change-routing-paths.interface.ts b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/interfaces/fines-acc-enf-court-change-routing-paths.interface.ts
new file mode 100644
index 0000000000..15bcf97360
--- /dev/null
+++ b/src/app/flows/fines/fines-acc/fines-acc-enf-court-change/interfaces/fines-acc-enf-court-change-routing-paths.interface.ts
@@ -0,0 +1,8 @@
+import { IChildRoutingPaths } from '@hmcts/opal-frontend-common/pages/routing/interfaces';
+
+export interface IFinesAccEnfCourtChangeRoutingPaths extends IChildRoutingPaths {
+ root: string;
+ children: {
+ change: string;
+ };
+}
diff --git a/src/app/flows/fines/fines-acc/routing/fines-acc.routes.ts b/src/app/flows/fines/fines-acc/routing/fines-acc.routes.ts
index e8420f4f79..ecf7e3eb11 100644
--- a/src/app/flows/fines/fines-acc/routing/fines-acc.routes.ts
+++ b/src/app/flows/fines/fines-acc/routing/fines-acc.routes.ts
@@ -22,6 +22,9 @@ import { fetchLocalJusticeAreasResolver } from '../../routing/resolvers/fetch-re
import { fetchEnforcersResolver } from '../../routing/resolvers/fetch-results-with-params-resolver/fetch-enforcers-resolver';
import { FINES_ACC_ENF_OVERRIDE_ADD_CHANGE_ROUTING_TITLES } from '../fines-acc-enf-override-add-change/constants/fines-acc-enf-override-add-change-routing-titles.constant';
import { FINES_ACC_ENF_OVERRIDE_ADD_CHANGE_ROUTING_PATHS } from '../fines-acc-enf-override-add-change/constants/fines-acc-enf-override-add-change-routing-paths.constant';
+import { FINES_ACC_ENF_COURT_CHANGE_ROUTING_PATHS } from '../fines-acc-enf-court-change/constants/fines-acc-enf-court-change-routing-paths.constant';
+import { FINES_ACC_ENF_COURT_CHANGE_ROUTING_TITLES } from '../fines-acc-enf-court-change/constants/fines-acc-enf-court-change-routing-titles.constant';
+import { fetchCourtsResolver } from './resolvers/fetch-courts-resolver/fetch-courts.resolver';
const accRootPermissionIds = FINES_PERMISSIONS;
@@ -194,6 +197,23 @@ export const routing: Routes = [
enforcersRefData: fetchEnforcersResolver,
},
},
+ {
+ path: `${FINES_ACC_DEFENDANT_ROUTING_PATHS.children.enforcement}/${FINES_ACC_ENF_COURT_CHANGE_ROUTING_PATHS.root}/${FINES_ACC_ENF_COURT_CHANGE_ROUTING_PATHS.children.change}`,
+ loadComponent: () =>
+ import('../fines-acc-enf-court-change/fines-acc-enf-court-change.component').then(
+ (c) => c.FinesAccEnfCourtChangeComponent,
+ ),
+ canActivate: [routePermissionsGuard, finesAccStateGuard],
+ canDeactivate: [canDeactivateGuard],
+ data: {
+ title: FINES_ACC_ENF_COURT_CHANGE_ROUTING_TITLES.children.change,
+ routePermissionId: [accRootPermissionIds['account-maintenance']],
+ },
+ resolve: {
+ title: TitleResolver,
+ courtsRefData: fetchCourtsResolver,
+ },
+ },
],
},
{
diff --git a/src/app/flows/fines/fines-acc/routing/resolvers/fetch-courts-resolver/fetch-courts.resolver.spec.ts b/src/app/flows/fines/fines-acc/routing/resolvers/fetch-courts-resolver/fetch-courts.resolver.spec.ts
new file mode 100644
index 0000000000..becb6deb52
--- /dev/null
+++ b/src/app/flows/fines/fines-acc/routing/resolvers/fetch-courts-resolver/fetch-courts.resolver.spec.ts
@@ -0,0 +1,43 @@
+import { TestBed } from '@angular/core/testing';
+import { ActivatedRouteSnapshot, ResolveFn, RouterStateSnapshot } from '@angular/router';
+import { beforeEach, describe, expect, it, vi } from 'vitest';
+import { Observable, of } from 'rxjs';
+import { fetchCourtsResolver } from './fetch-courts.resolver';
+import { OpalFines } from '@services/fines/opal-fines-service/opal-fines.service';
+import { FinesAccountStore } from '../../../stores/fines-acc.store';
+import { IOpalFinesCourtRefData } from '@services/fines/opal-fines-service/interfaces/opal-fines-court-ref-data.interface';
+
+describe('fetchCourtsResolver', () => {
+ const executeResolver: ResolveFn = (...resolverParameters) =>
+ TestBed.runInInjectionContext(() => fetchCourtsResolver(...resolverParameters));
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ providers: [
+ {
+ provide: OpalFines,
+ useValue: {
+ getCourts: vi.fn().mockReturnValue(of({ count: 1, refData: [] })),
+ },
+ },
+ {
+ provide: FinesAccountStore,
+ useValue: {
+ business_unit_id: vi.fn().mockReturnValue('123'),
+ },
+ },
+ ],
+ });
+ });
+
+ it('should fetch courts for the current account business unit', () => {
+ const opalFinesService = TestBed.inject(OpalFines);
+ const result = executeResolver(
+ {} as ActivatedRouteSnapshot,
+ {} as RouterStateSnapshot,
+ ) as Observable;
+
+ result.subscribe((value: IOpalFinesCourtRefData) => expect(value).toEqual({ count: 1, refData: [] }));
+ expect(opalFinesService.getCourts).toHaveBeenCalledWith(123);
+ });
+});
diff --git a/src/app/flows/fines/fines-acc/routing/resolvers/fetch-courts-resolver/fetch-courts.resolver.ts b/src/app/flows/fines/fines-acc/routing/resolvers/fetch-courts-resolver/fetch-courts.resolver.ts
new file mode 100644
index 0000000000..38912799b5
--- /dev/null
+++ b/src/app/flows/fines/fines-acc/routing/resolvers/fetch-courts-resolver/fetch-courts.resolver.ts
@@ -0,0 +1,13 @@
+import { ResolveFn } from '@angular/router';
+import { inject } from '@angular/core';
+import { Observable } from 'rxjs';
+import { OpalFines } from '@services/fines/opal-fines-service/opal-fines.service';
+import { IOpalFinesCourtRefData } from '@services/fines/opal-fines-service/interfaces/opal-fines-court-ref-data.interface';
+import { FinesAccountStore } from '../../../stores/fines-acc.store';
+
+export const fetchCourtsResolver: ResolveFn = (): Observable => {
+ const opalFinesService = inject(OpalFines);
+ const finesAccStore = inject(FinesAccountStore);
+
+ return opalFinesService.getCourts(Number(finesAccStore.business_unit_id()));
+};
diff --git a/src/app/flows/fines/fines-acc/services/fines-acc-payload.service.spec.ts b/src/app/flows/fines/fines-acc/services/fines-acc-payload.service.spec.ts
index 74a28b2b30..a450eecfcd 100644
--- a/src/app/flows/fines/fines-acc/services/fines-acc-payload.service.spec.ts
+++ b/src/app/flows/fines/fines-acc/services/fines-acc-payload.service.spec.ts
@@ -14,6 +14,7 @@ import { IOpalFinesAccountDefendantAccountParty } from '../../services/opal-fine
import { OPAL_FINES_ACCOUNT_DEFENDANT_ACCOUNT_PARTY_MOCK } from '../../services/opal-fines-service/mocks/opal-fines-account-defendant-account-party.mock';
import { OPAL_FINES_ACCOUNT_DEFENDANT_AT_A_GLANCE_MOCK } from '@services/fines/opal-fines-service/mocks/opal-fines-account-defendant-at-a-glance.mock';
import { IFinesAccAddCommentsFormState } from '../fines-acc-comments-add/interfaces/fines-acc-comments-add-form-state.interface';
+import { IFinesAccEnfCourtChangeFormState } from '../fines-acc-enf-court-change/interfaces/fines-acc-enf-court-change-form-state.interface';
import { FINES_MAC_MAP_TRANSFORM_ITEMS_CONFIG } from '../../fines-mac/services/fines-mac-payload/constants/fines-mac-map-transform-items-config.constant';
import { MOCK_EMPTY_FINES_ACC_PARTY_ADD_AMEND_CONVERT_FORM_DATA } from '../fines-acc-party-add-amend-convert/mocks/fines-acc-party-add-amend-convert-form-empty.mock';
import { FINES_ACC_MINOR_CREDITOR_DETAILS_HEADER_MOCK } from '../fines-acc-minor-creditor-details/mocks/fines-acc-minor-creditor-details-header.mock';
@@ -545,6 +546,7 @@ describe('FinesAccPayloadService', () => {
free_text_note_2: 'Updated note 2',
free_text_note_3: 'Updated note 3',
},
+ enforcement_court: null,
enforcement_override: null,
});
});
@@ -566,6 +568,7 @@ describe('FinesAccPayloadService', () => {
free_text_note_2: null,
free_text_note_3: null,
},
+ enforcement_court: null,
enforcement_override: null,
});
});
@@ -631,6 +634,22 @@ describe('FinesAccPayloadService', () => {
});
});
+ describe('buildEnforcementCourtFormPayload', () => {
+ it('should build the correct payload for an enforcement court change', () => {
+ const formState: IFinesAccEnfCourtChangeFormState = {
+ facc_enf_court: 202,
+ };
+
+ const result = service.buildEnforcementCourtFormPayload(formState);
+
+ expect(result).toEqual({
+ enforcement_court: {
+ court_id: 202,
+ },
+ });
+ });
+ });
+
describe('transformPaymentTermsPayload', () => {
it('should return form structure with nestedFlow false', () => {
const mockPaymentTermsData = {
diff --git a/src/app/flows/fines/fines-acc/services/fines-acc-payload.service.ts b/src/app/flows/fines/fines-acc/services/fines-acc-payload.service.ts
index 06959f87ef..5f4e82f506 100644
--- a/src/app/flows/fines/fines-acc/services/fines-acc-payload.service.ts
+++ b/src/app/flows/fines/fines-acc/services/fines-acc-payload.service.ts
@@ -27,6 +27,7 @@ import { buildAccountPartyFromFormState } from './utils/fines-acc-payload-build-
import { IOpalFinesAccountMinorCreditorDetailsHeader } from '../fines-acc-minor-creditor-details/interfaces/fines-acc-minor-creditor-details-header.interface';
import { IFinesAccEnfOverrideAddChangeFormState } from '../fines-acc-enf-override-add-change/interfaces/fines-acc-enf-override-add-change-form-state.interface';
import { OPAL_FINES_DEFENDANT_ACCOUNT_PATCH_PAYLOAD_DEFAULTS } from '../../services/opal-fines-service/constants/opal-fines-defendant-account-patch-payload-defaults.constant';
+import { IFinesAccEnfCourtChangeFormState } from '../fines-acc-enf-court-change/interfaces/fines-acc-enf-court-change-form-state.interface';
@Injectable({
providedIn: 'root',
@@ -210,6 +211,23 @@ export class FinesAccPayloadService {
};
}
+ /**
+ * Transforms the given IFinesAccEnfCourtChangeFormState into an update payload
+ * for the defendant account API.
+ *
+ * @param formState - The form state containing the enforcement court data
+ * @returns The transformed payload for updating the defendant account
+ */
+ public buildEnforcementCourtFormPayload(
+ formState: IFinesAccEnfCourtChangeFormState,
+ ): IOpalFinesUpdateDefendantAccountPayload {
+ return {
+ enforcement_court: {
+ court_id: Number(formState.facc_enf_court),
+ },
+ };
+ }
+
/**
* Transforms the given finesMacPayload object by applying the transformations
diff --git a/src/app/flows/fines/services/opal-fines-service/constants/opal-fines-defendant-account-patch-payload-defaults.constant.ts b/src/app/flows/fines/services/opal-fines-service/constants/opal-fines-defendant-account-patch-payload-defaults.constant.ts
index b9fb0ce6fd..5e3a45c17e 100644
--- a/src/app/flows/fines/services/opal-fines-service/constants/opal-fines-defendant-account-patch-payload-defaults.constant.ts
+++ b/src/app/flows/fines/services/opal-fines-service/constants/opal-fines-defendant-account-patch-payload-defaults.constant.ts
@@ -2,5 +2,6 @@ import { IOpalFinesUpdateDefendantAccountPayload } from '../interfaces/opal-fine
export const OPAL_FINES_DEFENDANT_ACCOUNT_PATCH_PAYLOAD_DEFAULTS: IOpalFinesUpdateDefendantAccountPayload = {
comment_and_notes: null,
+ enforcement_court: null,
enforcement_override: null,
};
diff --git a/src/app/flows/fines/services/opal-fines-service/interfaces/opal-fines-update-defendant-account-enforcement-court.interface.ts b/src/app/flows/fines/services/opal-fines-service/interfaces/opal-fines-update-defendant-account-enforcement-court.interface.ts
new file mode 100644
index 0000000000..ef515645ef
--- /dev/null
+++ b/src/app/flows/fines/services/opal-fines-service/interfaces/opal-fines-update-defendant-account-enforcement-court.interface.ts
@@ -0,0 +1,3 @@
+export interface IOpalFinesUpdateDefendantAccountEnforcementCourt {
+ court_id: number;
+}
diff --git a/src/app/flows/fines/services/opal-fines-service/interfaces/opal-fines-update-defendant-account.interface.ts b/src/app/flows/fines/services/opal-fines-service/interfaces/opal-fines-update-defendant-account.interface.ts
index 09d92d1f52..2126cebb42 100644
--- a/src/app/flows/fines/services/opal-fines-service/interfaces/opal-fines-update-defendant-account.interface.ts
+++ b/src/app/flows/fines/services/opal-fines-service/interfaces/opal-fines-update-defendant-account.interface.ts
@@ -1,10 +1,12 @@
import { IOpalFinesUpdateDefendantAccountCommentsNotes } from './opal-fines-update-defendant-account-comments-notes.interface';
+import { IOpalFinesUpdateDefendantAccountEnforcementCourt } from './opal-fines-update-defendant-account-enforcement-court.interface';
import { IOpalFinesUpdateDefendantAccountEnforcementOverride } from './opal-fines-update-defendant-account-enforcement-override.interface';
/**
* Interface for the payload to update a defendant account *Subject to change
*/
export interface IOpalFinesUpdateDefendantAccountPayload {
- comment_and_notes: IOpalFinesUpdateDefendantAccountCommentsNotes | null;
- enforcement_override: IOpalFinesUpdateDefendantAccountEnforcementOverride | null;
+ comment_and_notes?: IOpalFinesUpdateDefendantAccountCommentsNotes | null;
+ enforcement_court?: IOpalFinesUpdateDefendantAccountEnforcementCourt | null;
+ enforcement_override?: IOpalFinesUpdateDefendantAccountEnforcementOverride | null;
}