forked from Yara724/api
YARA-1072
This commit is contained in:
@@ -378,7 +378,10 @@ export class ExpertClaimService {
|
||||
return this.blameRequestDbService.findById(id);
|
||||
}
|
||||
|
||||
private async assertExpertActorOnClaim(claim: any, actor: any): Promise<void> {
|
||||
private async assertExpertActorOnClaim(
|
||||
claim: any,
|
||||
actor: any,
|
||||
): Promise<void> {
|
||||
const blame = await this.loadBlameForClaim(claim);
|
||||
assertClaimCaseForExpertActor(claim, actor, blame);
|
||||
}
|
||||
@@ -2462,9 +2465,15 @@ export class ExpertClaimService {
|
||||
*/
|
||||
async assignClaimForReviewV2(
|
||||
claimRequestId: string,
|
||||
actor: { sub: string; fullName?: string; clientKey?: string; role?: string },
|
||||
actor: {
|
||||
sub: string;
|
||||
fullName?: string;
|
||||
clientKey?: string;
|
||||
role?: string;
|
||||
},
|
||||
): Promise<ExpertFileAssignResultDto> {
|
||||
if ((actor as any).role !== RoleEnum.FIELD_EXPERT) requireActorClientKey(actor);
|
||||
if ((actor as any).role !== RoleEnum.FIELD_EXPERT)
|
||||
requireActorClientKey(actor);
|
||||
await this.expireClaimWorkflowLockV2IfStale(claimRequestId);
|
||||
|
||||
const claim = await this.claimCaseDbService.findById(claimRequestId);
|
||||
@@ -3003,7 +3012,9 @@ export class ExpertClaimService {
|
||||
if (priceCap !== null) {
|
||||
let totalPrice = 0;
|
||||
for (const part of reply.parts || []) {
|
||||
const parsed = this.parsePersianNumber(String(part.totalPayment ?? "0"));
|
||||
const parsed = this.parsePersianNumber(
|
||||
String(part.totalPayment ?? "0"),
|
||||
);
|
||||
if (!isNaN(parsed)) totalPrice += parsed;
|
||||
}
|
||||
if (totalPrice > priceCap) {
|
||||
@@ -3492,10 +3503,11 @@ export class ExpertClaimService {
|
||||
const clientKey = requireActorClientKey(actor);
|
||||
const expertId = String(actor.sub);
|
||||
const expertOid = new Types.ObjectId(expertId);
|
||||
const activityEvents = await this.expertFileActivityDbService.findByExpert(
|
||||
expertId,
|
||||
ExpertFileKind.CLAIM,
|
||||
);
|
||||
const activityEvents =
|
||||
await this.expertFileActivityDbService.findByExpert(
|
||||
expertId,
|
||||
ExpertFileKind.CLAIM,
|
||||
);
|
||||
const activityFileIds =
|
||||
expertPortfolioFileIdsFromActivityEvents(activityEvents);
|
||||
const orClauses: Record<string, unknown>[] = [
|
||||
@@ -3511,7 +3523,10 @@ export class ExpertClaimService {
|
||||
const rows =
|
||||
orClauses.length === 0
|
||||
? []
|
||||
: await this.claimCaseDbService.find({ $or: orClauses }, { lean: true });
|
||||
: await this.claimCaseDbService.find(
|
||||
{ $or: orClauses },
|
||||
{ lean: true },
|
||||
);
|
||||
const seen = new Set<string>();
|
||||
for (const doc of rows as Record<string, unknown>[]) {
|
||||
const id = String(doc._id ?? "");
|
||||
@@ -4234,54 +4249,54 @@ export class ExpertClaimService {
|
||||
}
|
||||
// Fall through to the detail build below (skip the damage-expert gate)
|
||||
} else {
|
||||
const isResendPending =
|
||||
claim.status === ClaimCaseStatus.WAITING_FOR_USER_RESEND;
|
||||
const isResendPending =
|
||||
claim.status === ClaimCaseStatus.WAITING_FOR_USER_RESEND;
|
||||
|
||||
const assignedForReviewById = String(
|
||||
(claim.workflow as any)?.assignedForReviewBy?.actorId ?? "",
|
||||
);
|
||||
const lockEnforced = this.isClaimV2WorkflowLockCurrentlyEnforced(claim);
|
||||
const lockedById = String(claim.workflow?.lockedBy?.actorId ?? "");
|
||||
const isAssignedToMe =
|
||||
!!assignedForReviewById && assignedForReviewById === actorId;
|
||||
|
||||
// Gate: must satisfy at least one bucket
|
||||
if (
|
||||
!isDamageExpertPhase &&
|
||||
!isFactorValidationPending &&
|
||||
!isResendPending &&
|
||||
!isAssignedToMe
|
||||
) {
|
||||
throw new ForbiddenException(
|
||||
`This claim is not available for expert review. Current status: ${claim.status}`,
|
||||
const assignedForReviewById = String(
|
||||
(claim.workflow as any)?.assignedForReviewBy?.actorId ?? "",
|
||||
);
|
||||
}
|
||||
const lockEnforced = this.isClaimV2WorkflowLockCurrentlyEnforced(claim);
|
||||
const lockedById = String(claim.workflow?.lockedBy?.actorId ?? "");
|
||||
const isAssignedToMe =
|
||||
!!assignedForReviewById && assignedForReviewById === actorId;
|
||||
|
||||
const isAvailable =
|
||||
isDamageExpertPhase && !assignedForReviewById && !lockEnforced;
|
||||
const isLockedByMe = lockEnforced && lockedById === actorId;
|
||||
const isFactorValidationOpen = isFactorValidationPending;
|
||||
|
||||
if (
|
||||
!isAvailable &&
|
||||
!isAssignedToMe &&
|
||||
!isLockedByMe &&
|
||||
!isFactorValidationOpen
|
||||
) {
|
||||
if (lockEnforced && lockedById && lockedById !== actorId) {
|
||||
// Gate: must satisfy at least one bucket
|
||||
if (
|
||||
!isDamageExpertPhase &&
|
||||
!isFactorValidationPending &&
|
||||
!isResendPending &&
|
||||
!isAssignedToMe
|
||||
) {
|
||||
throw new ForbiddenException(
|
||||
`This claim is locked by another expert: ${claim.workflow?.lockedBy?.actorName}`,
|
||||
`This claim is not available for expert review. Current status: ${claim.status}`,
|
||||
);
|
||||
}
|
||||
if (assignedForReviewById && assignedForReviewById !== actorId) {
|
||||
|
||||
const isAvailable =
|
||||
isDamageExpertPhase && !assignedForReviewById && !lockEnforced;
|
||||
const isLockedByMe = lockEnforced && lockedById === actorId;
|
||||
const isFactorValidationOpen = isFactorValidationPending;
|
||||
|
||||
if (
|
||||
!isAvailable &&
|
||||
!isAssignedToMe &&
|
||||
!isLockedByMe &&
|
||||
!isFactorValidationOpen
|
||||
) {
|
||||
if (lockEnforced && lockedById && lockedById !== actorId) {
|
||||
throw new ForbiddenException(
|
||||
`This claim is locked by another expert: ${claim.workflow?.lockedBy?.actorName}`,
|
||||
);
|
||||
}
|
||||
if (assignedForReviewById && assignedForReviewById !== actorId) {
|
||||
throw new ForbiddenException(
|
||||
"This claim has been assigned to another expert.",
|
||||
);
|
||||
}
|
||||
throw new ForbiddenException(
|
||||
"This claim has been assigned to another expert.",
|
||||
"You do not have permission to view this claim.",
|
||||
);
|
||||
}
|
||||
throw new ForbiddenException(
|
||||
"You do not have permission to view this claim.",
|
||||
);
|
||||
}
|
||||
} // end damage-expert gate (else block)
|
||||
|
||||
// Build requiredDocuments map
|
||||
@@ -4513,9 +4528,10 @@ export class ExpertClaimService {
|
||||
carAngles,
|
||||
damagedParts,
|
||||
awaitingFactorValidation: isFactorValidationPending,
|
||||
evaluation: evaluationForApi as
|
||||
| ClaimDetailV2ResponseDto["evaluation"]
|
||||
| undefined,
|
||||
evaluation:
|
||||
(evaluationForApi as
|
||||
| ClaimDetailV2ResponseDto["evaluation"]
|
||||
| undefined) || (enrichedEvaluation as any),
|
||||
videoCapture,
|
||||
blameCase: blameCaseForApi,
|
||||
blameExpertDecision,
|
||||
|
||||
Reference in New Issue
Block a user