This commit is contained in:
2026-04-06 14:15:31 +03:30
parent f77da50d1f
commit 1b68a81204
5 changed files with 144 additions and 30 deletions

View File

@@ -4100,7 +4100,7 @@ export class RequestManagementService {
roadCondition: formData.firstPartyDescription?.roadCondition,
lightCondition: formData.firstPartyDescription?.lightCondition,
},
location: formData.firstPartyLocation,
location: req.parties?.[0]?.location,
carBodyFirstForm: {
car: !!formData.carBodyForm.car,
object: !!formData.carBodyForm.object,
@@ -4110,20 +4110,19 @@ export class RequestManagementService {
req.parties = [firstParty];
req.workflow = {
currentStep: WorkflowStep.WAITING_FOR_SIGNATURES as any,
nextStep: undefined,
currentStep: WorkflowStep.FIRST_LOCATION as any,
nextStep: WorkflowStep.WAITING_FOR_SIGNATURES as any,
completedSteps: [
WorkflowStep.CREATED,
WorkflowStep.CAR_BODY_ACCIDENT_TYPE,
WorkflowStep.FIRST_VIDEO,
WorkflowStep.FIRST_INITIAL_FORM,
WorkflowStep.FIRST_LOCATION,
WorkflowStep.FIRST_VOICE,
WorkflowStep.FIRST_DESCRIPTION,
].filter((s) => s),
locked: false,
};
req.status = CaseStatus.WAITING_FOR_SIGNATURES;
req.status = CaseStatus.OPEN;
req.blameStatus = BlameStatus.AGREED;
(req as any).filledBy = FilledBy.EXPERT;
@@ -4181,7 +4180,6 @@ export class RequestManagementService {
userId: Types.ObjectId,
initialForm: any,
plateDto: any,
locationDto: any,
desc: string,
role: PartyRole,
) => {
@@ -4229,7 +4227,7 @@ export class RequestManagementService {
financialCeiling: sandHubReport?.FinancialCvrCptl || sandHubReport?.FinancialCommitment,
},
statement: { description: desc },
location: locationDto,
location: undefined,
evidence: {},
};
};
@@ -4239,7 +4237,6 @@ export class RequestManagementService {
firstPartyUserId,
formData.firstPartyInitialForm,
formData.firstPartyPlate,
formData.firstPartyLocation,
formData.firstPartyDescription?.desc || "",
PartyRole.FIRST,
);
@@ -4248,7 +4245,6 @@ export class RequestManagementService {
secondPartyUserId,
formData.secondParty.initialForm,
formData.secondParty.plate,
formData.secondParty.location,
formData.secondParty.description?.desc || "",
PartyRole.SECOND,
);
@@ -4261,24 +4257,22 @@ export class RequestManagementService {
if (!req.expert) req.expert = {} as any;
req.expert.decision = { guiltyPartyId: new Types.ObjectId(guiltyPartyId) } as any;
req.workflow = {
currentStep: WorkflowStep.WAITING_FOR_SIGNATURES as any,
nextStep: undefined,
currentStep: WorkflowStep.FIRST_LOCATION as any,
nextStep: WorkflowStep.SECOND_LOCATION as any,
completedSteps: [
WorkflowStep.CREATED,
WorkflowStep.FIRST_BLAME_CONFESSION,
WorkflowStep.FIRST_VIDEO,
WorkflowStep.FIRST_INITIAL_FORM,
WorkflowStep.FIRST_LOCATION,
WorkflowStep.FIRST_VOICE,
WorkflowStep.FIRST_DESCRIPTION,
WorkflowStep.SECOND_INITIAL_FORM,
WorkflowStep.SECOND_LOCATION,
WorkflowStep.SECOND_VOICE,
WorkflowStep.SECOND_DESCRIPTION,
].filter((s) => s),
locked: false,
};
req.status = CaseStatus.WAITING_FOR_SIGNATURES;
req.status = CaseStatus.OPEN;
req.blameStatus = BlameStatus.AGREED;
(req as any).filledBy = FilledBy.EXPERT;
@@ -4302,6 +4296,90 @@ export class RequestManagementService {
};
}
/**
* V2: Expert submits location(s) for expert-initiated IN_PERSON blame.
* This is separated from complete-blame-data to support dedicated location UI step.
*/
async expertAddLocationsForBlameV2(
expert: any,
requestId: string,
dto: { firstPartyLocation: LocationDto; secondPartyLocation?: LocationDto },
): Promise<any> {
const req = await this.blameRequestDbService.findById(requestId);
if (!req) throw new NotFoundException("Request not found");
if (
(!req.expertInitiated && !req.registrarInitiated) ||
req.creationMethod !== CreationMethod.IN_PERSON
) {
throw new BadRequestException(
"This endpoint is only for expert-initiated IN_PERSON blame files.",
);
}
this.verifyExpertAccessForBlameV2(req, expert);
const firstIdx = this.getPartyIndex(req, PartyRole.FIRST);
if (firstIdx === -1) throw new BadRequestException("First party not found");
if (!dto?.firstPartyLocation) {
throw new BadRequestException("firstPartyLocation is required");
}
req.parties[firstIdx].location = dto.firstPartyLocation as any;
if (req.type === BlameRequestType.THIRD_PARTY) {
const secondIdx = this.getPartyIndex(req, PartyRole.SECOND);
if (secondIdx === -1) throw new BadRequestException("Second party not found");
if (!dto?.secondPartyLocation) {
throw new BadRequestException(
"secondPartyLocation is required for THIRD_PARTY",
);
}
req.parties[secondIdx].location = dto.secondPartyLocation as any;
}
const completed = Array.isArray(req.workflow?.completedSteps)
? req.workflow.completedSteps
: [];
if (!completed.includes(WorkflowStep.FIRST_LOCATION as any)) {
completed.push(WorkflowStep.FIRST_LOCATION as any);
}
if (
req.type === BlameRequestType.THIRD_PARTY &&
!completed.includes(WorkflowStep.SECOND_LOCATION as any)
) {
completed.push(WorkflowStep.SECOND_LOCATION as any);
}
req.workflow = {
...(req.workflow || {}),
currentStep: WorkflowStep.WAITING_FOR_SIGNATURES as any,
nextStep: undefined,
completedSteps: completed,
locked: false,
} as any;
req.status = CaseStatus.WAITING_FOR_SIGNATURES;
if (!Array.isArray(req.history)) req.history = [];
req.history.push({
type: "EXPERT_ADDED_LOCATIONS_V2",
actor: {
actorId: new Types.ObjectId(expert.sub),
actorName: `${expert.firstName || ""} ${expert.lastName || ""}`.trim(),
actorType: expert?.role === RoleEnum.REGISTRAR ? "registrar" : "field_expert",
},
metadata: {
hasFirstLocation: true,
hasSecondLocation: req.type === BlameRequestType.THIRD_PARTY,
},
} as any);
await (req as any).save();
return {
requestId: req._id,
publicId: req.publicId,
workflow: req.workflow,
status: req.status,
};
}
/**
* V2: Expert uploads video for expert-initiated BlameRequest (first party).
*/