forked from Yara724/api
Fix v3 mirror flow
This commit is contained in:
@@ -15,6 +15,12 @@ export class ClaimListItemV2Dto {
|
||||
})
|
||||
status: string;
|
||||
|
||||
@ApiPropertyOptional({
|
||||
description: "Calculated unified blame+claim lifecycle status",
|
||||
example: "WAITING_FOR_DAMAGE_EXPERT",
|
||||
})
|
||||
unifiedFileStatus?: string;
|
||||
|
||||
@ApiProperty({ description: 'Workflow step', example: 'USER_SUBMISSION_COMPLETE' })
|
||||
currentStep: string;
|
||||
|
||||
|
||||
@@ -142,6 +142,11 @@ import {
|
||||
import { getClaimV2TotalPaymentCapToman } from "src/constants/repair-amount-limits";
|
||||
import { ListQueryV2Dto } from "src/common/dto/list-query-v2.dto";
|
||||
import { applyListQueryV2 } from "src/helpers/list-query-v2";
|
||||
import {
|
||||
countUnifiedFileStatuses,
|
||||
getUnifiedFileStatusCatalog,
|
||||
resolveUnifiedFileStatus,
|
||||
} from "src/helpers/unified-file-status";
|
||||
import { buildEnrichedDamagedParts } from "./dto/claim-damaged-part.enricher";
|
||||
import { canonicalizeResendDocumentKey } from "src/helpers/claim-resend-document-keys";
|
||||
|
||||
@@ -3411,6 +3416,144 @@ export class ExpertClaimService {
|
||||
return buckets;
|
||||
}
|
||||
|
||||
async getUnifiedFileStatusReportV2(actor: any) {
|
||||
const { claims, blameById } =
|
||||
await this.collectClaimPortfolioWithBlame(actor);
|
||||
return {
|
||||
statuses: getUnifiedFileStatusCatalog(),
|
||||
counts: countUnifiedFileStatuses(
|
||||
claims.map((c) => {
|
||||
const blame = c.blameRequestId
|
||||
? blameById.get(String(c.blameRequestId))
|
||||
: undefined;
|
||||
return {
|
||||
blameStatus: blame?.status,
|
||||
claimStatus: c.status,
|
||||
};
|
||||
}),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
private async collectClaimPortfolioWithBlame(actor: any): Promise<{
|
||||
claims: any[];
|
||||
blameById: Map<string, any>;
|
||||
}> {
|
||||
let claims: any[] = [];
|
||||
if (actor.role === RoleEnum.FIELD_EXPERT) {
|
||||
const expertOid = new Types.ObjectId(actor.sub);
|
||||
const expertBlameIds = await this.blameRequestDbService
|
||||
.find(
|
||||
{ expertInitiated: true, initiatedByFieldExpertId: expertOid },
|
||||
{ select: "_id", lean: true },
|
||||
)
|
||||
.then((docs) => docs.map((d) => (d as { _id: unknown })._id));
|
||||
const claimOr: Record<string, unknown>[] = [
|
||||
{ initiatedByFieldExpertId: expertOid },
|
||||
];
|
||||
if (expertBlameIds.length > 0) {
|
||||
claimOr.push({ blameRequestId: { $in: expertBlameIds } });
|
||||
}
|
||||
claims = (await this.claimCaseDbService.find({ $or: claimOr })) as any[];
|
||||
} else {
|
||||
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 activityFileIds =
|
||||
expertPortfolioFileIdsFromActivityEvents(activityEvents);
|
||||
const orClauses: Record<string, unknown>[] = [
|
||||
{ "workflow.lockedBy.actorId": expertOid },
|
||||
{ "evaluation.damageExpertReply.actorDetail.actorId": expertOid },
|
||||
{ "evaluation.damageExpertReplyFinal.actorDetail.actorId": expertOid },
|
||||
{ "evaluation.damageExpertResend.requestedByExpertId": expertOid },
|
||||
];
|
||||
const activityOids = objectIdsFromStringSet(activityFileIds);
|
||||
if (activityOids.length > 0) {
|
||||
orClauses.push({ _id: { $in: activityOids } });
|
||||
}
|
||||
const rows =
|
||||
orClauses.length === 0
|
||||
? []
|
||||
: 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 ?? "");
|
||||
if (seen.has(id)) continue;
|
||||
if (
|
||||
!claimDocInExpertPortfolio(doc, expertId, activityFileIds, clientKey)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
seen.add(id);
|
||||
claims.push(doc);
|
||||
}
|
||||
}
|
||||
|
||||
const blameIds = [
|
||||
...new Set(
|
||||
claims
|
||||
.map((c) => c.blameRequestId?.toString())
|
||||
.filter((id): id is string => !!id),
|
||||
),
|
||||
];
|
||||
const blames =
|
||||
blameIds.length > 0
|
||||
? ((await this.blameRequestDbService.find(
|
||||
{
|
||||
_id: { $in: blameIds.map((id) => new Types.ObjectId(id)) },
|
||||
},
|
||||
{ lean: true, select: "status publicId" },
|
||||
)) as any[])
|
||||
: [];
|
||||
const blameById = new Map<string, any>(
|
||||
blames.map((b) => [String(b._id), b]),
|
||||
);
|
||||
return { claims, blameById };
|
||||
}
|
||||
|
||||
private paginateClaimListV2(
|
||||
list: ClaimListItemV2Dto[],
|
||||
query: ListQueryV2Dto,
|
||||
): GetClaimListV2ResponseDto {
|
||||
let filtered = list;
|
||||
if (query.unifiedStatus) {
|
||||
filtered = list.filter(
|
||||
(item) => item.unifiedFileStatus === query.unifiedStatus,
|
||||
);
|
||||
}
|
||||
const paged = applyListQueryV2(
|
||||
filtered,
|
||||
{
|
||||
publicId: (r) => r.publicId,
|
||||
createdAt: (r) => r.createdAt,
|
||||
requestNo: (r) => r.publicId,
|
||||
status: (r) => r.unifiedFileStatus ?? r.status,
|
||||
searchExtras: (r) =>
|
||||
[
|
||||
r.claimRequestId,
|
||||
r.currentStep,
|
||||
r.vehicle?.carName,
|
||||
r.vehicle?.carModel,
|
||||
r.blameRequestType,
|
||||
r.unifiedFileStatus,
|
||||
r.status,
|
||||
].filter(Boolean) as string[],
|
||||
},
|
||||
query,
|
||||
);
|
||||
return {
|
||||
list: paged.list,
|
||||
total: paged.total,
|
||||
page: paged.page,
|
||||
limit: paged.limit,
|
||||
totalPages: paged.totalPages,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* V2: Get claim list for damage expert
|
||||
*
|
||||
@@ -3581,6 +3724,10 @@ export class ExpertClaimService {
|
||||
claimRequestId: c._id.toString(),
|
||||
publicId: c.publicId,
|
||||
status: statusForList,
|
||||
unifiedFileStatus: resolveUnifiedFileStatus({
|
||||
blameStatus: blame?.status,
|
||||
claimStatus: c.status,
|
||||
}),
|
||||
currentStep: c.workflow?.currentStep || "",
|
||||
locked: lockActive,
|
||||
lockedBy:
|
||||
@@ -3601,32 +3748,7 @@ export class ExpertClaimService {
|
||||
};
|
||||
}) as ClaimListItemV2Dto[];
|
||||
|
||||
const paged = applyListQueryV2(
|
||||
list,
|
||||
{
|
||||
publicId: (r) => r.publicId,
|
||||
createdAt: (r) => r.createdAt,
|
||||
requestNo: (r) => r.publicId,
|
||||
status: (r) => r.status,
|
||||
searchExtras: (r) =>
|
||||
[
|
||||
r.claimRequestId,
|
||||
r.currentStep,
|
||||
r.vehicle?.carName,
|
||||
r.vehicle?.carModel,
|
||||
r.blameRequestType,
|
||||
].filter(Boolean) as string[],
|
||||
},
|
||||
query,
|
||||
);
|
||||
|
||||
return {
|
||||
list: paged.list,
|
||||
total: paged.total,
|
||||
page: paged.page,
|
||||
limit: paged.limit,
|
||||
totalPages: paged.totalPages,
|
||||
};
|
||||
return this.paginateClaimListV2(list, query);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3687,6 +3809,10 @@ export class ExpertClaimService {
|
||||
claimRequestId: c._id.toString(),
|
||||
publicId: c.publicId,
|
||||
status: c.status,
|
||||
unifiedFileStatus: resolveUnifiedFileStatus({
|
||||
blameStatus: blame?.status,
|
||||
claimStatus: c.status,
|
||||
}),
|
||||
currentStep: c.workflow?.currentStep || "",
|
||||
locked: lockActive,
|
||||
lockedBy:
|
||||
@@ -3707,31 +3833,7 @@ export class ExpertClaimService {
|
||||
};
|
||||
}) as ClaimListItemV2Dto[];
|
||||
|
||||
const paged = applyListQueryV2(
|
||||
list,
|
||||
{
|
||||
publicId: (r) => r.publicId,
|
||||
createdAt: (r) => r.createdAt,
|
||||
requestNo: (r) => r.publicId,
|
||||
status: (r) => r.status,
|
||||
searchExtras: (r) =>
|
||||
[
|
||||
r.claimRequestId,
|
||||
r.currentStep,
|
||||
r.vehicle?.carName,
|
||||
r.vehicle?.carModel,
|
||||
].filter(Boolean) as string[],
|
||||
},
|
||||
query,
|
||||
);
|
||||
|
||||
return {
|
||||
list: paged.list,
|
||||
total: paged.total,
|
||||
page: paged.page,
|
||||
limit: paged.limit,
|
||||
totalPages: paged.totalPages,
|
||||
};
|
||||
return this.paginateClaimListV2(list, query);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -65,11 +65,22 @@ export class ExpertClaimV2Controller {
|
||||
private readonly claimRequestManagementService: ClaimRequestManagementService,
|
||||
) {}
|
||||
|
||||
@Get("report/unified-file-statuses")
|
||||
@ApiOperation({
|
||||
summary: "Unified file status catalog + counts (claim + linked blame)",
|
||||
description:
|
||||
"Calculatable statuses for this expert's claim portfolio. Filter lists with `unifiedStatus` query param.",
|
||||
})
|
||||
async getUnifiedFileStatusReportV2(@CurrentUser() actor: any) {
|
||||
return await this.expertClaimService.getUnifiedFileStatusReportV2(actor);
|
||||
}
|
||||
|
||||
@Get("report/status-counts")
|
||||
@ApiOperation({
|
||||
summary: "Count claim cases by grouped status bucket (this damage expert)",
|
||||
deprecated: true,
|
||||
description:
|
||||
"Counts only files in the acting expert’s portfolio: expertFileActivities (checked or handled), current workflow lock, or a prior damageExpertReply / damageExpertReplyFinal by this expert. IN_PROGRESS groups user-phase statuses before submission is complete (CREATED through CAPTURING_PART_DAMAGES). Other keys match ClaimCaseStatus. Does not include the open tenant queue unless this expert has touched the file.",
|
||||
"Legacy claim-only buckets. Prefer GET report/unified-file-statuses for blame+claim calculatable statuses.",
|
||||
})
|
||||
async getStatusReportBucketsV2(@CurrentUser() actor: any) {
|
||||
return await this.expertClaimService.getStatusReportBucketsV2(actor);
|
||||
@@ -116,7 +127,7 @@ export class ExpertClaimV2Controller {
|
||||
summary: "List available claim requests for damage expert",
|
||||
description:
|
||||
"Damage experts: tenant queue (`WAITING_FOR_DAMAGE_EXPERT`), locked/in-progress, factor validation. " +
|
||||
"Field experts: all claims linked to blame files they initiated (`initiatedByFieldExpertId` or matching `blameRequestId`). Optional query: `search`, `sortBy`, `sortOrder`, `page`, `limit`.",
|
||||
"Field experts: all claims linked to blame files they initiated (`initiatedByFieldExpertId` or matching `blameRequestId`). Optional query: `search`, `sortBy`, `sortOrder`, `page`, `limit`, `unifiedStatus`.",
|
||||
})
|
||||
@ApiResponse({ status: 200, type: GetClaimListV2ResponseDto })
|
||||
async getClaimListV2(
|
||||
|
||||
Reference in New Issue
Block a user