Skip to content

Commit ba3c419

Browse files
authored
WFPREV-777 reset to PROPOSED instead of DRAFT, maintain endorsement/approval depending on what has been unselected (#1019)
1 parent ebbd766 commit ba3c419

File tree

3 files changed

+35
-51
lines changed

3 files changed

+35
-51
lines changed

client/wfprev-war/src/main/angular/src/app/components/edit-project/endorsement-approval/endorsement-approval.component.spec.ts

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,8 @@ describe('EndorsementApprovalComponent', () => {
139139
expect(emittedFiscal!.businessAreaComment).toBe('New approval');
140140
});
141141

142-
it('should set planFiscalStatusCode to DRAFT if endorsement removed', async () => {
143-
spyOn<any>(component, 'confirmRevertToDraft').and.returnValue(Promise.resolve(true));
142+
it('should set planFiscalStatusCode to PROPOSED if endorsement removed', async () => {
143+
spyOn<any>(component, 'confirmRevertToProposed').and.returnValue(Promise.resolve(true));
144144

145145
const emitSpy = spyOn(component.saveEndorsement, 'emit');
146146
component.fiscal = {
@@ -155,7 +155,7 @@ describe('EndorsementApprovalComponent', () => {
155155
await component.onSave();
156156

157157
const emittedFiscal = emitSpy.calls.mostRecent()!.args[0];
158-
expect(emittedFiscal!.planFiscalStatusCode?.planFiscalStatusCode).toBe(FiscalStatuses.DRAFT);
158+
expect(emittedFiscal!.planFiscalStatusCode?.planFiscalStatusCode).toBe(FiscalStatuses.PROPOSED);
159159
});
160160

161161
it('should disable the form', () => {
@@ -259,9 +259,8 @@ describe('EndorsementApprovalComponent', () => {
259259
expect(component.isSaving).toBeFalse();
260260
});
261261

262-
it('resets to DRAFT and clears fields when endorsement removed (confirm = true)', async () => {
263-
// Arrange (shouldResetToDraft → endorsementRemoved = true, status not DRAFT/PROPOSED)
264-
spyOn<any>(component, 'confirmRevertToDraft').and.returnValue(Promise.resolve(true));
262+
it('resets to PROPOSED and clears fields when endorsement removed (confirm = true)', async () => {
263+
spyOn<any>(component, 'confirmRevertToProposed').and.returnValue(Promise.resolve(true));
265264
const emitSpy = spyOn(component.saveEndorsement, 'emit');
266265

267266
component.fiscal = {
@@ -285,11 +284,9 @@ describe('EndorsementApprovalComponent', () => {
285284
const { args } = emitSpy.calls.mostRecent();
286285
const payload = args[0] as ProjectFiscal;
287286

288-
// Forced DRAFT
289-
expect(payload.planFiscalStatusCode.planFiscalStatusCode).toBe(FiscalStatuses.DRAFT);
290-
// Approval forced false
291-
expect(payload.isApprovedInd).toBeFalse();
292-
287+
// Forced PROPOSED
288+
expect(payload.planFiscalStatusCode.planFiscalStatusCode).toBe(FiscalStatuses.PROPOSED);
289+
293290
// Endorsement cleared
294291
expect(payload.endorserName).toBeUndefined();
295292
expect(payload.endorsementTimestamp).toBeUndefined();
@@ -298,21 +295,12 @@ describe('EndorsementApprovalComponent', () => {
298295
expect(payload.endorsementEvalTimestamp).toBeUndefined();
299296
expect(payload.endorserUserGuid).toBeUndefined();
300297
expect(payload.endorserUserUserid).toBeUndefined();
301-
302-
// Approval cleared
303-
expect(payload.approvedTimestamp).toBeUndefined();
304-
expect(payload.approverName).toBeUndefined();
305-
expect(payload.approverUserGuid).toBeUndefined();
306-
expect(payload.approverUserUserid).toBeUndefined();
307-
expect(payload.businessAreaComment).toBeUndefined();
308-
309-
// Audit cleared per current implementation
310298
expect(payload.endorseApprUpdateUserid).toBeUndefined();
311299
expect(payload.endorseApprUpdatedTimestamp).toBeUndefined();
312300
});
313301

314-
it('resets to DRAFT and clears fields when approval removed (confirm = true)', async () => {
315-
spyOn<any>(component, 'confirmRevertToDraft').and.returnValue(Promise.resolve(true));
302+
it('resets to proposed and clears fields when approval removed (confirm = true)', async () => {
303+
spyOn<any>(component, 'confirmRevertToProposed').and.returnValue(Promise.resolve(true));
316304
const emitSpy = spyOn(component.saveEndorsement, 'emit');
317305

318306
component.fiscal = {
@@ -333,23 +321,17 @@ describe('EndorsementApprovalComponent', () => {
333321
const { args } = emitSpy.calls.mostRecent();
334322
const payload = args[0] as ProjectFiscal;
335323

336-
expect(payload.planFiscalStatusCode.planFiscalStatusCode).toBe(FiscalStatuses.DRAFT);
324+
expect(payload.planFiscalStatusCode.planFiscalStatusCode).toBe(FiscalStatuses.PROPOSED);
337325
expect(payload.isApprovedInd).toBeFalse();
338326
expect(payload.approvedTimestamp).toBeUndefined();
339327
expect(payload.approverName).toBeUndefined();
340328
expect(payload.approverUserGuid).toBeUndefined();
341329
expect(payload.approverUserUserid).toBeUndefined();
342330
expect(payload.businessAreaComment).toBeUndefined();
343-
expect(payload.endorserName).toBeUndefined();
344-
expect(payload.endorsementTimestamp).toBeUndefined();
345-
expect(payload.endorsementCode).toEqual({ endorsementCode: EndorsementCode.NOT_ENDORS });
346-
expect(payload.endorsementComment).toBeUndefined();
347-
expect(payload.endorseApprUpdateUserid).toBeUndefined();
348-
expect(payload.endorseApprUpdatedTimestamp).toBeUndefined();
349331
});
350332

351-
it('does not emit when user cancels the revert confirmation (shouldResetToDraft = true)', async () => {
352-
spyOn<any>(component, 'confirmRevertToDraft').and.returnValue(Promise.resolve(false));
333+
it('does not emit when user cancels the revert confirmation', async () => {
334+
spyOn<any>(component, 'confirmRevertToProposed').and.returnValue(Promise.resolve(false));
353335
const emitSpy = spyOn(component.saveEndorsement, 'emit');
354336

355337
component.fiscal = {
@@ -367,8 +349,8 @@ describe('EndorsementApprovalComponent', () => {
367349
expect(emitSpy).not.toHaveBeenCalled();
368350
});
369351

370-
it('calls confirmRevertToDraft with the current status when reverting', async () => {
371-
const confirmSpy = spyOn<any>(component, 'confirmRevertToDraft').and.returnValue(Promise.resolve(true));
352+
it('calls confirmRevertToProposed with the current status when reverting', async () => {
353+
const confirmSpy = spyOn<any>(component, 'confirmRevertToProposed').and.returnValue(Promise.resolve(true));
372354
const emitSpy = spyOn(component.saveEndorsement, 'emit');
373355

374356
component.fiscal = {

client/wfprev-war/src/main/angular/src/app/components/edit-project/endorsement-approval/endorsement-approval.component.ts

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,11 @@ export class EndorsementApprovalComponent implements OnChanges, OnInit {
143143
const endorsementRemoved = !formValue.endorseFiscalActivity;
144144
const approvalRemoved = !formValue.approveFiscalActivity;
145145
const currentStatusCode = this.fiscal?.planFiscalStatusCode?.planFiscalStatusCode;
146-
const shouldResetToDraft =
147-
(endorsementRemoved || approvalRemoved) &&
148-
currentStatusCode !== FiscalStatuses.DRAFT &&
149-
currentStatusCode !== FiscalStatuses.PROPOSED;
146+
const resetToProposedEndorsementRemoved = endorsementRemoved && currentStatusCode !== FiscalStatuses.DRAFT && currentStatusCode !== FiscalStatuses.PROPOSED;
147+
const resetToProposedApprovalRemoved = approvalRemoved && currentStatusCode !== FiscalStatuses.DRAFT && currentStatusCode !== FiscalStatuses.PROPOSED;
150148

151-
if (shouldResetToDraft) {
152-
const confirmed = await this.confirmRevertToDraft(currentStatusCode ?? '');
149+
if (resetToProposedEndorsementRemoved || resetToProposedApprovalRemoved) {
150+
const confirmed = await this.confirmRevertToProposed(currentStatusCode ?? '');
153151
if (!confirmed) return; // user cancelled
154152
}
155153

@@ -182,25 +180,29 @@ export class EndorsementApprovalComponent implements OnChanges, OnInit {
182180
endorseApprUpdatedTimestamp: currentUtc,
183181
};
184182

185-
// Status logic: (return to DRAFT if removed and not DRAFT/PROPOSED)
186-
// if reverting to draft, clear out endorsement/approval fields
187-
if (shouldResetToDraft) {
188-
updatedFiscal.planFiscalStatusCode = { planFiscalStatusCode: FiscalStatuses.DRAFT };
189-
updatedFiscal.isApprovedInd = false;
183+
// Status logic: (return to PROPOSED if removed and not DRAFT/PROPOSED)
184+
// if reverting to proposed, clear out endorsement or approval fields depending on which has been unselected
185+
if (resetToProposedEndorsementRemoved) {
186+
updatedFiscal.planFiscalStatusCode = { planFiscalStatusCode: FiscalStatuses.PROPOSED };
190187
updatedFiscal.endorserName = undefined;
191188
updatedFiscal.endorsementTimestamp = undefined;
192189
updatedFiscal.endorsementCode = { endorsementCode: EndorsementCode.NOT_ENDORS };
193190
updatedFiscal.endorsementComment = undefined;
194191
updatedFiscal.endorsementEvalTimestamp = undefined;
195192
updatedFiscal.endorserUserGuid = undefined;
196193
updatedFiscal.endorserUserUserid = undefined;
194+
updatedFiscal.endorseApprUpdateUserid = undefined;
195+
updatedFiscal.endorseApprUpdatedTimestamp = undefined;
196+
}
197+
198+
if (resetToProposedApprovalRemoved) {
199+
updatedFiscal.planFiscalStatusCode = { planFiscalStatusCode: FiscalStatuses.PROPOSED };
200+
updatedFiscal.isApprovedInd = false;
197201
updatedFiscal.approvedTimestamp = undefined;
198202
updatedFiscal.approverName = undefined;
199203
updatedFiscal.approverUserGuid = undefined;
200204
updatedFiscal.approverUserUserid = undefined;
201205
updatedFiscal.businessAreaComment = undefined;
202-
updatedFiscal.endorseApprUpdateUserid = undefined;
203-
updatedFiscal.endorseApprUpdatedTimestamp = undefined;
204206
}
205207

206208
this.saveEndorsement.emit(updatedFiscal);
@@ -269,18 +271,18 @@ export class EndorsementApprovalComponent implements OnChanges, OnInit {
269271
}
270272
}
271273

272-
async confirmRevertToDraft(currentStatusCode: string): Promise<boolean> {
274+
async confirmRevertToProposed(currentStatusCode: string): Promise<boolean> {
273275
if (!currentStatusCode) return false;
274276

275277
// Parse status to plain English if it is IN_PROG
276278
// The remaining status do not require such parsing
277279
const currentStatus = currentStatusCode === 'IN_PROG' ? "In Progress" : capitalizeFirstLetter(currentStatusCode);
278-
const message = `You are about to change the status of this Fiscal Activity from ${currentStatus} to Draft. Do you wish to continue?`
280+
const message = `You are about to change the status of this Fiscal Activity from ${currentStatus} to Proposed. Do you wish to continue?`
279281

280282
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
281283
data: {
282284
indicator: 'confirm-fiscal-status-update',
283-
title: `Confirm Change to Draft`,
285+
title: `Confirm Change to Proposed`,
284286
message: message
285287
},
286288
width: '600px',

server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProjectFiscalService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ public class ProjectFiscalService implements CommonService {
4848
private static final Map<String, Set<String>> VALID_TRANSITIONS = Map.of(
4949
DRAFT, Set.of(DRAFT, PROPOSED, PREPARED, CANCELLED),
5050
PROPOSED, Set.of(DRAFT, PROPOSED, PREPARED, CANCELLED),
51-
PREPARED, Set.of(DRAFT, PREPARED, IN_PROG, CANCELLED),
52-
IN_PROG, Set.of(DRAFT, COMPLETE, CANCELLED, IN_PROG),
51+
PREPARED, Set.of(DRAFT, PROPOSED, PREPARED, IN_PROG, CANCELLED),
52+
IN_PROG, Set.of(DRAFT, PROPOSED, COMPLETE, CANCELLED, IN_PROG),
5353
COMPLETE, Set.of(COMPLETE),
5454
CANCELLED, Set.of(CANCELLED)
5555
);

0 commit comments

Comments
 (0)