Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ <h2 [class]="style.heading">Enforcement status</h2>
? true
: false
"
(actionClick)="handleChangeCollectionOrder()"
>
<ng-container name>Collection Order status</ng-container>
<ng-container value>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,24 @@ describe('FinesAccDefendantDetailsEnforcementTab', () => {
expect(event.preventDefault).toHaveBeenCalled();
expect(eventEmitterSpy).toHaveBeenCalled();
});

it('should emit changeCollectionOrder when handleChangeCollectionOrder is called', () => {
const eventEmitterSpy = vi.spyOn(component.changeCollectionOrder, 'emit');
component.hasAccountMaintenancePermission = true;

component.handleChangeCollectionOrder();

expect(eventEmitterSpy).toHaveBeenCalledWith(
component.tabData.enforcement_overview.collection_order?.collection_order_flag ?? false,
);
});

it('should not emit changeCollectionOrder when the user lacks account maintenance permission', () => {
const eventEmitterSpy = vi.spyOn(component.changeCollectionOrder, 'emit');
component.hasAccountMaintenancePermission = false;

component.handleChangeCollectionOrder();

expect(eventEmitterSpy).not.toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export class FinesAccDefendantDetailsEnforcementTab {
@Input() hasAccountMaintenancePermission: boolean = false;
@Input() hasEnterEnforcementPermission: boolean = false;
@Output() addEnforcementOverride = new EventEmitter<void>();
@Output() changeCollectionOrder = new EventEmitter<boolean>();

/**
* Emits an event to add an enforcement override if the user has the necessary permissions and there is no existing enforcement override result.
Expand All @@ -53,4 +54,15 @@ export class FinesAccDefendantDetailsEnforcementTab {
this.addEnforcementOverride.emit();
}
}

/**
* Emits an event to change the collection order status.
*/
public handleChangeCollectionOrder(): void {
if (this.hasAccountMaintenancePermission) {
this.changeCollectionOrder.emit(
this.tabData.enforcement_overview.collection_order?.collection_order_flag ?? false,
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ <h2 opal-lib-custom-account-information-item-label>Business Unit:</h2>
[hasAccountMaintenancePermission]="hasPermission('account-maintenance')"
[hasEnterEnforcementPermission]="hasPermission('enter-enforcement')"
(addEnforcementOverride)="navigateToAddEnforcementOverridePage()"
(changeCollectionOrder)="navigateToChangeCollectionOrderPage($event)"
></app-fines-acc-defendant-details-enforcement-tab>
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,17 @@ describe('FinesAccDefendantDetailsComponent', () => {
);
});

it('should call router.navigate when navigateToChangeCollectionOrderPage is called', () => {
component.navigateToChangeCollectionOrderPage(true);
expect(routerSpy.navigate).toHaveBeenCalledWith(
[`../${FINES_ACC_DEFENDANT_ROUTING_PATHS.children.enforcement}/collection-order/change`],
{
relativeTo: component['activatedRoute'],
state: { currentCollectionOrderFlag: true },
},
);
});

it('should fetch the defendant tab data when fragment is changed to defendant', () => {
component['refreshFragment$'].next('defendant');
// Subscribe to trigger the pipe execution
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -458,4 +458,14 @@ export class FinesAccDefendantDetailsComponent extends AbstractTabData implement
relativeTo: this.activatedRoute,
});
}

/**
* Navigates to the change collection order page.
*/
public navigateToChangeCollectionOrderPage(currentCollectionOrderFlag: boolean): void {
this['router'].navigate([`../${FINES_ACC_DEFENDANT_ROUTING_PATHS.children.enforcement}/collection-order/change`], {
relativeTo: this.activatedRoute,
state: { currentCollectionOrderFlag },
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { IFinesAccEnfColloChangeFieldErrors } from '../interfaces/fines-acc-enf-collo-change-field-errors.interface';

export const FINES_ACC_ENF_COLLO_CHANGE_FIELD_ERRORS: IFinesAccEnfColloChangeFieldErrors = {
facc_enf_collection_order_made: {
required: {
message: 'Select whether the account is subject to a Collection Order',
priority: 1,
},
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { IFinesAccEnfColloChangeRoutingTitles } from '../interfaces/fines-acc-enf-collo-change-routing-titles.interface';

export const FINES_ACC_ENF_COLLO_CHANGE_ROUTING_TITLES: IFinesAccEnfColloChangeRoutingTitles = {
root: 'Collection Order',
children: {
change: 'Change Collection Order status',
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const FINES_ACC_ENF_COLLO_CHANGE_SUCCESS_MESSAGE = 'Collection Order status changed';
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<opal-lib-govuk-error-summary
[errors]="formErrorSummaryMessage"
(errorClick)="scrollTo($event)"
></opal-lib-govuk-error-summary>

<opal-lib-govuk-heading-with-caption
[captionText]="`${accountNumber} - ${partyName}`"
[headingText]="'Change Collection Order Status'"
headingClasses="govuk-heading-l govuk-!-margin-bottom-6"
>
</opal-lib-govuk-heading-with-caption>

<p class="govuk-body">If the status of a Collection Order is incorrect you can change it.</p>
<p class="govuk-body govuk-!-font-weight-bold">This will not issue a new notice.</p>
<p class="govuk-body">
To add a new Collection Order and issue a notice you should
<a
class="govuk-link govuk-link--no-visited-state"
href=""
id="facc_enf_collection_order_go_back"
(click)="handleRoute(defendantAccRoutingPaths.children.details, { fragment: 'enforcement', event: $event })"
>go back</a
>
and add an enforcement action.
</p>

<form (submit)="handleFormSubmit($event)" [formGroup]="form" class="govuk-form">
<opal-lib-govuk-radio
radioClasses="govuk-radios--inline"
fieldSetId="facc_enf_collection_order_made"
legendText="Is this account subject to a Collection Order?"
legendClasses="govuk-fieldset__legend--m"
[errors]="formControlErrorMessages['facc_enf_collection_order_made']"
>
<div
opal-lib-govuk-radios-item
labelText="Yes"
inputId="facc_enf_collection_order_made_true"
inputName="facc_enf_collection_order_made"
[inputValue]="true"
[control]="form.get('facc_enf_collection_order_made')"
></div>
<div
opal-lib-govuk-radios-item
labelText="No"
inputId="facc_enf_collection_order_made_false"
inputName="facc_enf_collection_order_made"
[inputValue]="false"
[control]="form.get('facc_enf_collection_order_made')"
></div>
</opal-lib-govuk-radio>

<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds govuk-!-margin-bottom-0">
<div class="govuk-button-group govuk-!-margin-bottom-0">
<opal-lib-govuk-button
buttonId="submitForm"
type="submit"
buttonClasses="nested-flow govuk-button--primary govuk-!-margin-bottom-0"
>
Change
</opal-lib-govuk-button>
<opal-lib-govuk-cancel-link
(linkClickEvent)="handleRoute(defendantAccRoutingPaths.children.details, { fragment: 'enforcement' })"
></opal-lib-govuk-cancel-link>
</div>
</div>
</div>
</form>
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ActivatedRoute } from '@angular/router';
import { beforeEach, describe, expect, it } from 'vitest';
import { FinesAccEnfColloChangeFormComponent } from './fines-acc-enf-collo-change-form.component';

describe('FinesAccEnfColloChangeFormComponent', () => {
let component: FinesAccEnfColloChangeFormComponent;
let fixture: ComponentFixture<FinesAccEnfColloChangeFormComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [FinesAccEnfColloChangeFormComponent],
providers: [{ provide: ActivatedRoute, useValue: { snapshot: { params: {}, data: {} } } }],
}).compileComponents();

fixture = TestBed.createComponent(FinesAccEnfColloChangeFormComponent);
component = fixture.componentInstance;
component.accountNumber = '177A';
component.partyName = 'Mr Robert THOMSON';
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});

it('should initialize the collection order control', () => {
expect(component.form.get('facc_enf_collection_order_made')).toBeTruthy();
expect(component.form.get('facc_enf_collection_order_made')?.value).toBeNull();
});

it('should render the account caption in account-number-first format', () => {
const compiled = fixture.nativeElement as HTMLElement;
expect(compiled.textContent).toContain('177A - Mr Robert THOMSON');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnInit } 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 { 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 {
GovukRadioComponent,
GovukRadiosItemComponent,
} from '@hmcts/opal-frontend-common/components/govuk/govuk-radio';
import { FINES_ACC_DEFENDANT_ROUTING_PATHS } from '../../routing/constants/fines-acc-defendant-routing-paths.constant';
import { IFinesAccEnfColloChangeFormState } from '../interfaces/fines-acc-enf-collo-change-form-state.interface';
import { FINES_ACC_ENF_COLLO_CHANGE_FIELD_ERRORS } from '../constants/fines-acc-enf-collo-change-field-errors.constant';

@Component({
selector: 'app-fines-acc-enf-collo-change-form',
imports: [
FormsModule,
ReactiveFormsModule,
GovukButtonComponent,
GovukCancelLinkComponent,
GovukErrorSummaryComponent,
GovukHeadingWithCaptionComponent,
GovukRadioComponent,
GovukRadiosItemComponent,
],
templateUrl: './fines-acc-enf-collo-change-form.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
})
export class FinesAccEnfColloChangeFormComponent extends AbstractFormBaseComponent implements OnInit {
protected override fieldErrors: IAbstractFormBaseFieldErrors = {
...FINES_ACC_ENF_COLLO_CHANGE_FIELD_ERRORS,
};
protected override formSubmit = new EventEmitter<IAbstractFormBaseForm<IFinesAccEnfColloChangeFormState>>();
public override formControlErrorMessages: IAbstractFormControlErrorMessage = {};
public readonly defendantAccRoutingPaths = FINES_ACC_DEFENDANT_ROUTING_PATHS;

@Input({ required: true }) partyName!: string;
@Input({ required: true }) accountNumber!: string;

/**
* Creates the form group for changing the Collection Order status.
*/
private setupForm(): void {
this.form = new FormGroup({
facc_enf_collection_order_made: new FormControl<boolean | null>(null, Validators.required),
});
}

/**
* Initialises the form before running the shared abstract form setup.
*/
public override ngOnInit(): void {
this.setupForm();
super.ngOnInit();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<div class="govuk-grid-column-two-thirds">
<app-fines-acc-enf-collo-change-form
[accountNumber]="accountNumber"
[partyName]="partyName"
(unsavedChanges)="handleUnsavedChanges($event)"
(formSubmit)="handleSubmit($event)"
></app-fines-acc-enf-collo-change-form>
</div>
Loading
Loading