forked from Yara724/api
merge upstream
This commit is contained in:
@@ -77,7 +77,7 @@ export class UserAuthService {
|
|||||||
role: "user",
|
role: "user",
|
||||||
};
|
};
|
||||||
const accToken = this.jwtService.sign(payload, {
|
const accToken = this.jwtService.sign(payload, {
|
||||||
secret: `${process.env.JWT_SECRET}`,
|
secret: `${process.env.JWT_SECRET}`, expiresIn: '1h'
|
||||||
});
|
});
|
||||||
await this.userDbService.findOneAndUpdate(
|
await this.userDbService.findOneAndUpdate(
|
||||||
{ username: user.username },
|
{ username: user.username },
|
||||||
|
|||||||
@@ -138,6 +138,25 @@ export class ClaimDetailV2ResponseDto {
|
|||||||
})
|
})
|
||||||
requiresFileMakerApproval?: boolean;
|
requiresFileMakerApproval?: boolean;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({
|
||||||
|
description:
|
||||||
|
"V5 only. Number of times the FileMaker has rejected this claim (0–2). When 2, the next action must be approval.",
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
|
fileMakerRejectionCount?: number;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({
|
||||||
|
description: "V5 only. Reason text from the most recent FileMaker rejection.",
|
||||||
|
example: "قیمت نامعقول",
|
||||||
|
})
|
||||||
|
fileMakerRejectionReason?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({
|
||||||
|
description: "V5 only. ObjectId of the FileMaker who must approve (or has approved) this claim.",
|
||||||
|
example: "6a43a2689faee3d20bf24030",
|
||||||
|
})
|
||||||
|
fileMakerApprovalActorId?: string;
|
||||||
|
|
||||||
@ApiPropertyOptional({
|
@ApiPropertyOptional({
|
||||||
description:
|
description:
|
||||||
"Slice of `claim.evaluation` exposed to the damage expert. " +
|
"Slice of `claim.evaluation` exposed to the damage expert. " +
|
||||||
|
|||||||
@@ -971,7 +971,7 @@ export class ExpertClaimService {
|
|||||||
daghi: {
|
daghi: {
|
||||||
option: part.daghi.option,
|
option: part.daghi.option,
|
||||||
...(part.daghi.price && { price: part.daghi.price }),
|
...(part.daghi.price && { price: part.daghi.price }),
|
||||||
...(part.daghi.branchId && {
|
...(part.daghi.branchId && Types.ObjectId.isValid(part.daghi.branchId) && {
|
||||||
branchId: new Types.ObjectId(part.daghi.branchId),
|
branchId: new Types.ObjectId(part.daghi.branchId),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
@@ -2671,32 +2671,39 @@ export class ExpertClaimService {
|
|||||||
if (!reviewerBlame) {
|
if (!reviewerBlame) {
|
||||||
throw new NotFoundException("Linked blame file not found.");
|
throw new NotFoundException("Linked blame file not found.");
|
||||||
}
|
}
|
||||||
const blameStatus = (reviewerBlame as any).status as string;
|
|
||||||
if (blameStatus === "WAITING_FOR_FILE_REVIEWER") {
|
|
||||||
// Phase 1: blame-assign path
|
|
||||||
return this.assignFileReviewerToV4Blame(claimRequestId, claim, actor);
|
|
||||||
}
|
|
||||||
// Phase 2: blame is past the initial assignment step.
|
|
||||||
// Only the reviewer who was assigned during Phase 1 may proceed.
|
|
||||||
const assignedReviewerId = (reviewerBlame as any).assignedFileReviewerId
|
const assignedReviewerId = (reviewerBlame as any).assignedFileReviewerId
|
||||||
? String((reviewerBlame as any).assignedFileReviewerId)
|
? String((reviewerBlame as any).assignedFileReviewerId)
|
||||||
: null;
|
: null;
|
||||||
if (!assignedReviewerId) {
|
const blameStatus = (reviewerBlame as any).status as string;
|
||||||
throw new BadRequestException({
|
|
||||||
success: false,
|
if (blameStatus === "WAITING_FOR_FILE_REVIEWER") {
|
||||||
status: "unavailable" satisfies ExpertFileAssignStatus,
|
if (assignedReviewerId && assignedReviewerId === actor.sub) {
|
||||||
message: "No reviewer has been assigned to this file yet.",
|
// Reviewer already assigned (e.g. after a FileMaker rejection that reset
|
||||||
});
|
// blame back to WAITING_FOR_FILE_REVIEWER) — skip Phase 1 and fall
|
||||||
|
// through to the damage-expert workflow lock below.
|
||||||
|
} else {
|
||||||
|
// Phase 1: first-time blame assignment
|
||||||
|
return this.assignFileReviewerToV4Blame(claimRequestId, claim, actor);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Phase 2: blame is past the initial assignment step.
|
||||||
|
// Only the reviewer who was assigned during Phase 1 may proceed.
|
||||||
|
if (!assignedReviewerId) {
|
||||||
|
throw new BadRequestException({
|
||||||
|
success: false,
|
||||||
|
status: "unavailable" satisfies ExpertFileAssignStatus,
|
||||||
|
message: "No reviewer has been assigned to this file yet.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (assignedReviewerId !== actor.sub) {
|
||||||
|
throw new ConflictException({
|
||||||
|
success: false,
|
||||||
|
status: "locked" satisfies ExpertFileAssignStatus,
|
||||||
|
message: "This file is assigned to another reviewer.",
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (assignedReviewerId !== actor.sub) {
|
// Fall through to the damage-expert workflow lock below.
|
||||||
throw new ConflictException({
|
|
||||||
success: false,
|
|
||||||
status: "locked" satisfies ExpertFileAssignStatus,
|
|
||||||
message: "This file is assigned to another reviewer.",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Assigned reviewer — fall through to the damage-expert workflow lock below.
|
|
||||||
// (actor.role stays FILE_REVIEWER; assertExpertActorOnClaim checks clientKey scope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.assertExpertActorOnClaim(claim, actor);
|
await this.assertExpertActorOnClaim(claim, actor);
|
||||||
@@ -2777,10 +2784,16 @@ export class ExpertClaimService {
|
|||||||
const now = new Date();
|
const now = new Date();
|
||||||
const lockSnapshot = await this.snapshotDamageExpert(actor.sub);
|
const lockSnapshot = await this.snapshotDamageExpert(actor.sub);
|
||||||
const expiredAt = new Date(now.getTime() + EXPERT_WORKFLOW_LOCK_TTL_MS);
|
const expiredAt = new Date(now.getTime() + EXPERT_WORKFLOW_LOCK_TTL_MS);
|
||||||
const actorType = isFieldExpertOwner ? "field_expert" : "damage_expert";
|
const actorType = isFieldExpertOwner
|
||||||
|
? "field_expert"
|
||||||
|
: (actor as any).role === RoleEnum.FILE_REVIEWER
|
||||||
|
? "file_reviewer"
|
||||||
|
: "damage_expert";
|
||||||
const actorRoleLabel = isFieldExpertOwner
|
const actorRoleLabel = isFieldExpertOwner
|
||||||
? ("field_expert" as const)
|
? ("field_expert" as const)
|
||||||
: ("damage_expert" as const);
|
: (actor as any).role === RoleEnum.FILE_REVIEWER
|
||||||
|
? ("file_reviewer" as const)
|
||||||
|
: ("damage_expert" as const);
|
||||||
|
|
||||||
const lockedByPayload = {
|
const lockedByPayload = {
|
||||||
actorId: expertOid,
|
actorId: expertOid,
|
||||||
@@ -2834,7 +2847,13 @@ export class ExpertClaimService {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!claim.workflow?.assignedForReviewBy) {
|
// Update assignedForReviewBy whenever a FILE_REVIEWER re-locks after a
|
||||||
|
// FileMaker rejection — the stale payload (from a prior damage-expert cycle)
|
||||||
|
// must be replaced with the actual reviewer so submit checks pass.
|
||||||
|
if (
|
||||||
|
!claim.workflow?.assignedForReviewBy ||
|
||||||
|
(actor as any).role === RoleEnum.FILE_REVIEWER
|
||||||
|
) {
|
||||||
baseLockUpdate["workflow.assignedForReviewBy"] = lockedByPayload;
|
baseLockUpdate["workflow.assignedForReviewBy"] = lockedByPayload;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3363,6 +3382,12 @@ export class ExpertClaimService {
|
|||||||
const nextCaseStatus = claimCaseStatusAfterExpertReplyV2(processedParts);
|
const nextCaseStatus = claimCaseStatusAfterExpertReplyV2(processedParts);
|
||||||
let nextClaimStatus = ClaimStatus.APPROVED;
|
let nextClaimStatus = ClaimStatus.APPROVED;
|
||||||
|
|
||||||
|
// V5 flow: FileMaker must approve before the owner is asked to sign.
|
||||||
|
// When no factor upload is needed, skip the owner-sign step entirely here
|
||||||
|
// and park the claim at WAITING_FOR_FILE_MAKER_APPROVAL. The owner SMS
|
||||||
|
// and INSURER_REVIEW status are emitted by fileMakerApproveV5 instead.
|
||||||
|
const isV5Claim = !!(claim as any).requiresFileMakerApproval;
|
||||||
|
|
||||||
if (needsFactorUpload) {
|
if (needsFactorUpload) {
|
||||||
nextClaimStatus = ClaimStatus.NEEDS_REVISION;
|
nextClaimStatus = ClaimStatus.NEEDS_REVISION;
|
||||||
if (mixedFactorAndPrice) {
|
if (mixedFactorAndPrice) {
|
||||||
@@ -3372,6 +3397,10 @@ export class ExpertClaimService {
|
|||||||
currentStep = ClaimWorkflowStep.OWNER_UPLOAD_FACTOR_DOCUMENTS;
|
currentStep = ClaimWorkflowStep.OWNER_UPLOAD_FACTOR_DOCUMENTS;
|
||||||
nextWorkflowStep = ClaimWorkflowStep.EXPERT_COST_EVALUATION;
|
nextWorkflowStep = ClaimWorkflowStep.EXPERT_COST_EVALUATION;
|
||||||
}
|
}
|
||||||
|
} else if (isV5Claim) {
|
||||||
|
// V5, no factors: hold at WAITING_FOR_FILE_MAKER_APPROVAL
|
||||||
|
currentStep = ClaimWorkflowStep.INSURER_REVIEW;
|
||||||
|
nextWorkflowStep = ClaimWorkflowStep.CLAIM_COMPLETED;
|
||||||
}
|
}
|
||||||
|
|
||||||
const mergedSelectedParts = [...ownerSelectedParts];
|
const mergedSelectedParts = [...ownerSelectedParts];
|
||||||
@@ -3389,7 +3418,9 @@ export class ExpertClaimService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const updatePayload: Record<string, unknown> = {
|
const updatePayload: Record<string, unknown> = {
|
||||||
status: nextCaseStatus,
|
status: isV5Claim && !needsFactorUpload
|
||||||
|
? ClaimCaseStatus.WAITING_FOR_FILE_MAKER_APPROVAL
|
||||||
|
: nextCaseStatus,
|
||||||
claimStatus: nextClaimStatus,
|
claimStatus: nextClaimStatus,
|
||||||
...(expertAddedParts.length > 0
|
...(expertAddedParts.length > 0
|
||||||
? { "damage.selectedParts": mergedSelectedParts }
|
? { "damage.selectedParts": mergedSelectedParts }
|
||||||
@@ -3445,8 +3476,9 @@ export class ExpertClaimService {
|
|||||||
idempotencyKey: `claim:${claimRequestId}:handled:${actor.sub}`,
|
idempotencyKey: `claim:${claimRequestId}:handled:${actor.sub}`,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// V5: owner SMS is sent by fileMakerApproveV5 after FileMaker approval.
|
||||||
const ownerPhoneNotify = await this.resolveClaimOwnerPhone(claim);
|
const ownerPhoneNotify = await this.resolveClaimOwnerPhone(claim);
|
||||||
if (ownerPhoneNotify && !needsFactorUpload) {
|
if (ownerPhoneNotify && !needsFactorUpload && !isV5Claim) {
|
||||||
const expertLastName =
|
const expertLastName =
|
||||||
actor?.fullName?.trim()?.split(/\s+/).pop() || "کارشناس";
|
actor?.fullName?.trim()?.split(/\s+/).pop() || "کارشناس";
|
||||||
await this.smsOrchestrationService.sendSignatureReviewNotice({
|
await this.smsOrchestrationService.sendSignatureReviewNotice({
|
||||||
@@ -3454,7 +3486,7 @@ export class ExpertClaimService {
|
|||||||
fileKind: "claim",
|
fileKind: "claim",
|
||||||
publicId: claim.publicId,
|
publicId: claim.publicId,
|
||||||
expertLastName,
|
expertLastName,
|
||||||
link: this.smsOrchestrationService.buildClaimLink(String(claim._id), "v1"),
|
link: this.smsOrchestrationService.buildClaimLink(String(claim._id), "v2"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5073,6 +5105,11 @@ export class ExpertClaimService {
|
|||||||
damagedParts,
|
damagedParts,
|
||||||
awaitingFactorValidation: isFactorValidationPending,
|
awaitingFactorValidation: isFactorValidationPending,
|
||||||
requiresFileMakerApproval: !!(claim as any).requiresFileMakerApproval,
|
requiresFileMakerApproval: !!(claim as any).requiresFileMakerApproval,
|
||||||
|
fileMakerRejectionCount: (claim as any).fileMakerRejectionCount ?? 0,
|
||||||
|
fileMakerRejectionReason: (claim as any).fileMakerRejectionReason ?? undefined,
|
||||||
|
fileMakerApprovalActorId: (claim as any).fileMakerApprovalActorId
|
||||||
|
? String((claim as any).fileMakerApprovalActorId)
|
||||||
|
: undefined,
|
||||||
evaluation:
|
evaluation:
|
||||||
(evaluationForApi as
|
(evaluationForApi as
|
||||||
| ClaimDetailV2ResponseDto["evaluation"]
|
| ClaimDetailV2ResponseDto["evaluation"]
|
||||||
|
|||||||
@@ -64,26 +64,19 @@ export class FileMakerClaimApprovalV5Controller {
|
|||||||
@ApiOperation({
|
@ApiOperation({
|
||||||
summary: "Approve the completed claim (FileMaker V5)",
|
summary: "Approve the completed claim (FileMaker V5)",
|
||||||
description:
|
description:
|
||||||
"Approves a claim that is in WAITING_FOR_FILE_MAKER_APPROVAL status. " +
|
"Approves a claim that is in `WAITING_FOR_FILE_MAKER_APPROVAL` status. " +
|
||||||
"Marks the claim COMPLETED and triggers fanavaran submission.",
|
"Moves the claim to `INSURER_REVIEW_AWAITING_OWNER_SIGN` and sends the owner an SMS " +
|
||||||
|
"with a signature link. Fanavaran submission is triggered automatically after the " +
|
||||||
|
"owner signs.",
|
||||||
})
|
})
|
||||||
async approve(
|
async approve(
|
||||||
@Param("claimRequestId") claimRequestId: string,
|
@Param("claimRequestId") claimRequestId: string,
|
||||||
@CurrentUser() fileMaker: any,
|
@CurrentUser() fileMaker: any,
|
||||||
) {
|
) {
|
||||||
const result = await this.requestManagementService.fileMakerApproveV5(
|
return this.requestManagementService.fileMakerApproveV5(
|
||||||
fileMaker,
|
fileMaker,
|
||||||
claimRequestId,
|
claimRequestId,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Trigger fanavaran auto-submit now that the claim is COMPLETED and the gate
|
|
||||||
// (requiresFileMakerApproval) has been cleared.
|
|
||||||
const fanavaran =
|
|
||||||
await this.claimRequestManagementService.autoSubmitToFanavaranV2OnClaimCompleted(
|
|
||||||
claimRequestId,
|
|
||||||
);
|
|
||||||
|
|
||||||
return { ...result, fanavaran };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post("reject/:claimRequestId")
|
@Post("reject/:claimRequestId")
|
||||||
|
|||||||
@@ -10389,28 +10389,53 @@ export class RequestManagementService {
|
|||||||
metadata: {},
|
metadata: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Move claim to COMPLETED and clear the approval gate
|
// V5 approval: move claim to INSURER_REVIEW_AWAITING_OWNER_SIGN so the
|
||||||
|
// owner can now sign. Clear requiresFileMakerApproval so that when the
|
||||||
|
// owner later signs and autoSubmitToFanavaranV2OnClaimCompleted runs, it
|
||||||
|
// does not re-intercept the claim as a pending V5 gate.
|
||||||
await this.claimCaseDbService.findByIdAndUpdate(claimRequestId, {
|
await this.claimCaseDbService.findByIdAndUpdate(claimRequestId, {
|
||||||
$set: {
|
$set: {
|
||||||
status: ClaimCaseStatus.COMPLETED,
|
status: ClaimCaseStatus.INSURER_REVIEW_AWAITING_OWNER_SIGN,
|
||||||
claimStatus: ClaimStatus.APPROVED,
|
claimStatus: ClaimStatus.APPROVED,
|
||||||
requiresFileMakerApproval: false,
|
requiresFileMakerApproval: false,
|
||||||
"workflow.currentStep": ClaimWorkflowStep.CLAIM_COMPLETED,
|
"workflow.currentStep": ClaimWorkflowStep.INSURER_REVIEW,
|
||||||
"workflow.nextStep": ClaimWorkflowStep.CLAIM_COMPLETED,
|
"workflow.nextStep": ClaimWorkflowStep.CLAIM_COMPLETED,
|
||||||
},
|
},
|
||||||
$push: {
|
$push: {
|
||||||
"workflow.completedSteps": ClaimWorkflowStep.INSURER_REVIEW,
|
|
||||||
history: historyEntry,
|
history: historyEntry,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Notify the owner that the claim is ready for their signature.
|
||||||
|
const notifyUserId = (claim as any).damagedPartyUserId ?? (claim as any).owner?.userId;
|
||||||
|
if (notifyUserId && claim.blameRequestId) {
|
||||||
|
const blame = await this.blameRequestDbService.findById(
|
||||||
|
String(claim.blameRequestId),
|
||||||
|
);
|
||||||
|
const ownerParty = (blame?.parties || []).find(
|
||||||
|
(p: any) =>
|
||||||
|
p?.person?.userId && String(p.person.userId) === String(notifyUserId),
|
||||||
|
);
|
||||||
|
const ownerPhone = ownerParty?.person?.phoneNumber
|
||||||
|
?? (await this.userDbService.findOne({ _id: new Types.ObjectId(String(notifyUserId)) }))?.mobile;
|
||||||
|
if (ownerPhone && typeof ownerPhone === "string") {
|
||||||
|
await this.smsOrchestrationService.sendSignatureReviewNotice({
|
||||||
|
receptor: ownerPhone,
|
||||||
|
fileKind: "claim",
|
||||||
|
publicId: claim.publicId,
|
||||||
|
expertLastName: actorName.split(/\s+/).pop() || "کارشناس",
|
||||||
|
link: this.smsOrchestrationService.buildClaimLink(claimRequestId, "v2"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
claimRequestId,
|
claimRequestId,
|
||||||
publicId: claim.publicId,
|
publicId: claim.publicId,
|
||||||
status: ClaimCaseStatus.COMPLETED,
|
status: ClaimCaseStatus.INSURER_REVIEW_AWAITING_OWNER_SIGN,
|
||||||
message:
|
message:
|
||||||
"Claim approved by FileMaker. Claim is now marked COMPLETED. " +
|
"Claim approved by FileMaker. Owner has been notified to sign. " +
|
||||||
"Proceed with fanavaran submission via the claim service.",
|
"Once the owner signs, the claim will be completed and submitted to Fanavaran.",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10467,6 +10492,25 @@ export class RequestManagementService {
|
|||||||
"workflow.nextStep": ClaimWorkflowStep.EXPERT_DAMAGE_ASSESSMENT,
|
"workflow.nextStep": ClaimWorkflowStep.EXPERT_DAMAGE_ASSESSMENT,
|
||||||
"workflow.locked": false,
|
"workflow.locked": false,
|
||||||
},
|
},
|
||||||
|
// Clear all stale lock fields and prior-cycle evaluation data so the
|
||||||
|
// FileReviewer starts a completely clean lock cycle:
|
||||||
|
// - workflow lock fields left over from the completed review cycle
|
||||||
|
// - damageExpertReply / damageExpertResend / ownerInsurerApproval /
|
||||||
|
// ownerPricedPartsApproval — all belong to the rejected cycle and
|
||||||
|
// must not bleed into the new one (resend fulfilledAt would block
|
||||||
|
// submitResendDocsV2; stale reply would mislead the frontend)
|
||||||
|
// - assignedForReviewBy is intentionally kept so the same reviewer
|
||||||
|
// is still scoped to this file on re-lock
|
||||||
|
$unset: {
|
||||||
|
"workflow.lockedAt": "",
|
||||||
|
"workflow.expiredAt": "",
|
||||||
|
"workflow.lockedBy": "",
|
||||||
|
"workflow.preLockQueueSnapshot": "",
|
||||||
|
"evaluation.damageExpertReply": "",
|
||||||
|
"evaluation.damageExpertResend": "",
|
||||||
|
"evaluation.ownerInsurerApproval": "",
|
||||||
|
"evaluation.ownerPricedPartsApproval": "",
|
||||||
|
},
|
||||||
$push: {
|
$push: {
|
||||||
history: {
|
history: {
|
||||||
type: "V5_FILE_MAKER_REJECTED",
|
type: "V5_FILE_MAKER_REJECTED",
|
||||||
@@ -10623,7 +10667,7 @@ export class RequestManagementService {
|
|||||||
agent: any,
|
agent: any,
|
||||||
requestId: string,
|
requestId: string,
|
||||||
dto: Omit<RunInquiriesV3Dto, "sheba">,
|
dto: Omit<RunInquiriesV3Dto, "sheba">,
|
||||||
): Promise<{ blameRequestId: string; message: string }> {
|
): Promise<Record<string, unknown>> {
|
||||||
if (agent?.role !== RoleEnum.CALL_CENTER) {
|
if (agent?.role !== RoleEnum.CALL_CENTER) {
|
||||||
throw new ForbiddenException("Only call-center agents can use this endpoint.");
|
throw new ForbiddenException("Only call-center agents can use this endpoint.");
|
||||||
}
|
}
|
||||||
@@ -10651,9 +10695,41 @@ export class RequestManagementService {
|
|||||||
});
|
});
|
||||||
await (req as any).save();
|
await (req as any).save();
|
||||||
|
|
||||||
|
// Return the inquiry-populated data so the agent can review before sending the link.
|
||||||
|
const firstPartyAfter = req.parties[firstIdx];
|
||||||
return {
|
return {
|
||||||
blameRequestId: requestId,
|
blameRequestId: requestId,
|
||||||
|
publicId: (req as any).publicId,
|
||||||
|
type: (req as any).type,
|
||||||
|
status: (req as any).status,
|
||||||
message: "Guilty-party inquiry complete. You can now send the blame link to the user.",
|
message: "Guilty-party inquiry complete. You can now send the blame link to the user.",
|
||||||
|
guiltyParty: {
|
||||||
|
vehicle: firstPartyAfter?.vehicle
|
||||||
|
? {
|
||||||
|
plateId: firstPartyAfter.vehicle.plateId,
|
||||||
|
name: firstPartyAfter.vehicle.name,
|
||||||
|
type: firstPartyAfter.vehicle.type,
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
insurance: firstPartyAfter?.insurance
|
||||||
|
? {
|
||||||
|
company: firstPartyAfter.insurance.company,
|
||||||
|
policyNumber: firstPartyAfter.insurance.policyNumber,
|
||||||
|
startDate: firstPartyAfter.insurance.startDate,
|
||||||
|
endDate: firstPartyAfter.insurance.endDate,
|
||||||
|
financialCeiling: (firstPartyAfter.insurance as any).financialCeiling,
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
person: firstPartyAfter?.person
|
||||||
|
? {
|
||||||
|
nationalCodeOfInsurer: firstPartyAfter.person.nationalCodeOfInsurer,
|
||||||
|
nationalCodeOfDriver: firstPartyAfter.person.nationalCodeOfDriver,
|
||||||
|
driverIsInsurer: firstPartyAfter.person.driverIsInsurer,
|
||||||
|
insurerBirthday: firstPartyAfter.person.insurerBirthday,
|
||||||
|
driverBirthday: firstPartyAfter.person.driverBirthday,
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10734,14 +10810,24 @@ export class RequestManagementService {
|
|||||||
type: (req as any).type,
|
type: (req as any).type,
|
||||||
status: (req as any).status,
|
status: (req as any).status,
|
||||||
blameStatus: (req as any).blameStatus,
|
blameStatus: (req as any).blameStatus,
|
||||||
workflow: (req as any).workflow,
|
workflow: {
|
||||||
|
currentStep: (req as any).workflow?.currentStep,
|
||||||
|
nextStep: (req as any).workflow?.nextStep,
|
||||||
|
completedSteps: (req as any).workflow?.completedSteps,
|
||||||
|
},
|
||||||
skipInitialFormStep: (req as any).skipInitialFormStep,
|
skipInitialFormStep: (req as any).skipInitialFormStep,
|
||||||
parties: ((req as any).parties ?? []).map((p: any) => ({
|
parties: ((req as any).parties ?? []).map((p: any) => ({
|
||||||
role: p.role,
|
role: p.role,
|
||||||
person: {
|
person: {
|
||||||
phoneNumber: p.person?.phoneNumber,
|
phoneNumber: p.person?.phoneNumber,
|
||||||
nationalCodeOfInsurer: p.person?.nationalCodeOfInsurer,
|
nationalCodeOfInsurer: p.person?.nationalCodeOfInsurer,
|
||||||
clientId: p.person?.clientId,
|
nationalCodeOfDriver: p.person?.nationalCodeOfDriver,
|
||||||
|
driverIsInsurer: p.person?.driverIsInsurer,
|
||||||
|
insurerBirthday: p.person?.insurerBirthday,
|
||||||
|
driverBirthday: p.person?.driverBirthday,
|
||||||
|
clientId: p.person?.clientId
|
||||||
|
? String(p.person.clientId)
|
||||||
|
: undefined,
|
||||||
},
|
},
|
||||||
insurance: p.insurance
|
insurance: p.insurance
|
||||||
? {
|
? {
|
||||||
@@ -10749,13 +10835,20 @@ export class RequestManagementService {
|
|||||||
policyNumber: p.insurance.policyNumber,
|
policyNumber: p.insurance.policyNumber,
|
||||||
startDate: p.insurance.startDate,
|
startDate: p.insurance.startDate,
|
||||||
endDate: p.insurance.endDate,
|
endDate: p.insurance.endDate,
|
||||||
|
financialCeiling: p.insurance.financialCeiling,
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
vehicle: p.vehicle
|
vehicle: p.vehicle
|
||||||
? { plateId: p.vehicle.plateId, name: p.vehicle.name }
|
? {
|
||||||
|
plateId: p.vehicle.plateId,
|
||||||
|
name: p.vehicle.name,
|
||||||
|
type: p.vehicle.type,
|
||||||
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
|
inquiryComplete: !!(p.person?.inquiriesCompleted),
|
||||||
})),
|
})),
|
||||||
createdAt: (req as any).createdAt,
|
createdAt: (req as any).createdAt,
|
||||||
|
updatedAt: (req as any).updatedAt,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user