Skip to content

Commit 0387af3

Browse files
authored
Merge pull request #501 from bcgov/feat/vendor-my-proposal-status-change
Feat/vendor my proposal status change
2 parents 772798d + 5e35ba8 commit 0387af3

File tree

28 files changed

+1045
-162
lines changed

28 files changed

+1045
-162
lines changed

src/back-end/lib/db/proposal/code-with-us.ts

Lines changed: 135 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -852,48 +852,95 @@ export const updateCWUProposal = tryDb<
852852
);
853853
});
854854

855+
/**
856+
* Internal function that updates a CWU proposal status.
857+
*/
858+
async function _updateCWUProposalStatusInternal(
859+
trx: Transaction,
860+
proposalId: Id,
861+
status: CWUProposalStatus,
862+
note: string,
863+
session: AuthenticatedSession
864+
): Promise<CWUProposal> {
865+
const now = new Date();
866+
867+
const [result] = await trx<RawCWUProposalHistoryRecord & { proposal: Id }>(
868+
"cwuProposalStatuses"
869+
).insert(
870+
{
871+
id: generateUuid(),
872+
proposal: proposalId,
873+
createdAt: now,
874+
createdBy: session.user.id,
875+
status,
876+
note
877+
},
878+
"*"
879+
);
880+
881+
// Update updatedAt/By stamp on proposal root record
882+
await trx("cwuProposals").where({ id: proposalId }).update({
883+
updatedAt: now,
884+
updatedBy: session.user.id
885+
});
886+
887+
if (!result) {
888+
throw new Error("unable to update proposal");
889+
}
890+
891+
const dbResult = await readOneCWUProposal(trx, result.proposal, session);
892+
if (isInvalid(dbResult) || !dbResult.value) {
893+
throw new Error("unable to update proposal");
894+
}
895+
896+
return dbResult.value;
897+
}
898+
855899
export const updateCWUProposalStatus = tryDb<
856900
[Id, CWUProposalStatus, string, AuthenticatedSession],
857901
CWUProposal
858902
>(async (connection, proposalId, status, note, session) => {
859-
const now = new Date();
860903
return valid(
861904
await connection.transaction(async (trx) => {
862-
const [result] = await connection<
863-
RawCWUProposalHistoryRecord & { proposal: Id }
864-
>("cwuProposalStatuses")
865-
.transacting(trx)
866-
.insert(
867-
{
868-
id: generateUuid(),
869-
proposal: proposalId,
870-
createdAt: now,
871-
createdBy: session.user.id,
872-
status,
873-
note
874-
},
875-
"*"
876-
);
877-
878-
// Update updatedAt/By stamp on proposal root record
879-
await connection("cwuProposals")
880-
.transacting(trx)
881-
.where({ id: proposalId })
882-
.update({
883-
updatedAt: now,
884-
updatedBy: session.user.id
885-
});
905+
return await _updateCWUProposalStatusInternal(
906+
trx,
907+
proposalId,
908+
status,
909+
note,
910+
session
911+
);
912+
})
913+
);
914+
});
886915

887-
if (!result) {
888-
throw new Error("unable to update proposal");
889-
}
916+
/**
917+
* Disqualifies a CWU proposal and updates the opportunity processing status in a single transaction.
918+
* This ensures both operations succeed or fail together.
919+
*/
920+
export const disqualifyCWUProposalAndUpdateOpportunity = tryDb<
921+
[Id, string, AuthenticatedSession],
922+
CWUProposal
923+
>(async (connection, proposalId, disqualificationReason, session) => {
924+
return valid(
925+
await connection.transaction(async (trx) => {
926+
// Update proposal status to disqualified
927+
const updatedProposal = await _updateCWUProposalStatusInternal(
928+
trx,
929+
proposalId,
930+
CWUProposalStatus.Disqualified,
931+
disqualificationReason,
932+
session
933+
);
890934

891-
const dbResult = await readOneCWUProposal(trx, result.proposal, session);
892-
if (isInvalid(dbResult) || !dbResult.value) {
893-
throw new Error("unable to update proposal");
894-
}
935+
// Check if opportunity should be moved to "Processing" status after disqualification
936+
const opportunityId = updatedProposal.opportunity.id;
937+
await checkAndUpdateCWUOpportunityProcessingStatus(
938+
trx,
939+
opportunityId,
940+
session
941+
);
895942

896-
return dbResult.value;
943+
return updatedProposal;
897944
})
898945
);
899946
});
@@ -970,11 +1017,66 @@ export const updateCWUProposalScore = tryDb<
9701017
throw new Error("unable to update proposal");
9711018
}
9721019

1020+
// updateCWUProposalScore was invoked -
1021+
// this proposal is now fully evaluated, check if we need to change the opportunity "Processing" status
1022+
const opportunityId = dbResult.value.opportunity.id;
1023+
await checkAndUpdateCWUOpportunityProcessingStatus(
1024+
trx,
1025+
opportunityId,
1026+
session
1027+
);
1028+
9731029
return dbResult.value;
9741030
})
9751031
);
9761032
});
9771033

1034+
/**
1035+
* Checks if all proposals for a CWU opportunity are evaluated and
1036+
* updates the opportunity status accordingly.
1037+
*/
1038+
export async function checkAndUpdateCWUOpportunityProcessingStatus(
1039+
connection: Connection,
1040+
opportunityId: Id,
1041+
session: AuthenticatedSession
1042+
): Promise<void> {
1043+
// Get all active proposals
1044+
const activeProposals = await generateCWUProposalQuery(connection)
1045+
.where({ "proposals.opportunity": opportunityId })
1046+
.whereNotIn("statuses.status", [
1047+
CWUProposalStatus.Withdrawn,
1048+
CWUProposalStatus.Disqualified,
1049+
CWUProposalStatus.Draft
1050+
]);
1051+
1052+
// Get current opportunity status
1053+
const currentOpportunity = await generateCWUOpportunityQuery(connection)
1054+
.where({ "opp.id": opportunityId })
1055+
.select("stat.status")
1056+
.first();
1057+
1058+
const currentStatus = currentOpportunity.status;
1059+
const totalProposalsCount = activeProposals.length;
1060+
const evaluatedCount = activeProposals.filter(
1061+
(p) => p.status === CWUProposalStatus.Evaluated
1062+
).length;
1063+
1064+
// All proposals are evaluated and opportunity is in EVALUATION, change to PROCESSING
1065+
if (
1066+
totalProposalsCount > 0 &&
1067+
evaluatedCount === totalProposalsCount &&
1068+
currentStatus === CWUOpportunityStatus.Evaluation
1069+
) {
1070+
await updateCWUOpportunityStatus(
1071+
connection,
1072+
opportunityId,
1073+
CWUOpportunityStatus.Processing,
1074+
"Automatically moved to Processing as all proposals have been evaluated.",
1075+
session
1076+
);
1077+
}
1078+
}
1079+
9781080
export const awardCWUProposal = tryDb<
9791081
[Id, string, AuthenticatedSession],
9801082
CWUProposal

0 commit comments

Comments
 (0)