forked from Yara724/api
YARA-853
This commit is contained in:
@@ -116,6 +116,18 @@ export class ExpertInsurerController {
|
||||
);
|
||||
}
|
||||
|
||||
@Get("files/:publicId")
|
||||
@ApiParam({ name: "publicId" })
|
||||
async getFileDetailsByPublicId(
|
||||
@CurrentUser() insurer,
|
||||
@Param("publicId") publicId: string,
|
||||
) {
|
||||
return await this.expertInsurerService.retrieveFileDetailsByPublicId(
|
||||
insurer.clientKey,
|
||||
publicId,
|
||||
);
|
||||
}
|
||||
|
||||
@Get("top-files")
|
||||
async getTopFiles(@CurrentUser() insurer) {
|
||||
return await this.expertInsurerService.getTopFilesForClient(
|
||||
|
||||
@@ -134,6 +134,19 @@ export class ExpertInsurerService {
|
||||
};
|
||||
}
|
||||
|
||||
private buildPartiesPreview(parties: any[] | undefined) {
|
||||
if (!Array.isArray(parties) || !parties.length) return undefined;
|
||||
return parties.map((p: any) => ({
|
||||
role: p?.role,
|
||||
fullName: p?.person?.fullName,
|
||||
vehicle: {
|
||||
carName: p?.vehicle?.carName ?? p?.vehicle?.name,
|
||||
carModel: p?.vehicle?.carModel ?? p?.vehicle?.model,
|
||||
plate: p?.vehicle?.plate ?? p?.vehicle?.plateId,
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
||||
private getCombinedFileScore(file: any): number | null {
|
||||
const insurerRating = file?.rating;
|
||||
const userRating = file?.userRating;
|
||||
@@ -165,11 +178,6 @@ export class ExpertInsurerService {
|
||||
.filter((f) =>
|
||||
(f?.parties || []).some((p) => String(p?.person?.clientId || "") === idStr),
|
||||
)
|
||||
.filter(
|
||||
(f) =>
|
||||
f?.status !== CaseStatus.OPEN &&
|
||||
f?.status !== CaseStatus.WAITING_FOR_SECOND_PARTY,
|
||||
)
|
||||
.map((f) => this.normalizeBlameCase(f));
|
||||
}
|
||||
|
||||
@@ -177,7 +185,7 @@ export class ExpertInsurerService {
|
||||
const all = (await this.claimCaseDbService.find({}, { lean: true })) as any[];
|
||||
const idStr = String(clientObjectId);
|
||||
return all
|
||||
.filter((f) => String(f?.owner?.userClientKey || "") === idStr)
|
||||
.filter((f) => claimCaseTouchesClient(f, idStr))
|
||||
.map((f) => this.normalizeClaimCase(f));
|
||||
}
|
||||
|
||||
@@ -405,7 +413,227 @@ export class ExpertInsurerService {
|
||||
this.getClientBlameFiles(id),
|
||||
this.getClientClaimFiles(id),
|
||||
]);
|
||||
return { blameFiles, claimFiles };
|
||||
|
||||
const byPublicId = new Map<
|
||||
string,
|
||||
{
|
||||
publicId: string;
|
||||
fileType?: string;
|
||||
parties?: Array<{
|
||||
role?: string;
|
||||
fullName?: string;
|
||||
vehicle?: {
|
||||
carName?: string;
|
||||
carModel?: string;
|
||||
plate?: string;
|
||||
};
|
||||
}>;
|
||||
blame?: {
|
||||
requestId?: string;
|
||||
requestNo?: string;
|
||||
status?: string;
|
||||
parties?: Array<{
|
||||
role?: string;
|
||||
fullName?: string;
|
||||
vehicle?: {
|
||||
carName?: string;
|
||||
carModel?: string;
|
||||
plate?: string;
|
||||
};
|
||||
}>;
|
||||
createdAt?: Date | string;
|
||||
updatedAt?: Date | string;
|
||||
};
|
||||
claim?: {
|
||||
requestId?: string;
|
||||
requestNo?: string;
|
||||
status?: string;
|
||||
claimStatus?: string;
|
||||
currentStep?: string;
|
||||
createdAt?: Date | string;
|
||||
updatedAt?: Date | string;
|
||||
};
|
||||
createdAt?: Date | string;
|
||||
updatedAt?: Date | string;
|
||||
}
|
||||
>();
|
||||
|
||||
for (const b of blameFiles) {
|
||||
const key = String((b as any).publicId || (b as any)._id || "");
|
||||
if (!key) continue;
|
||||
const prev = byPublicId.get(key) ?? { publicId: key };
|
||||
const partiesPreview = this.buildPartiesPreview((b as any).parties);
|
||||
prev.fileType = prev.fileType ?? (b as any).type;
|
||||
prev.blame = {
|
||||
requestId: (b as any)?._id?.toString?.() || String((b as any)?._id || ""),
|
||||
requestNo: (b as any).requestNo || String((b as any).requestNumber || ""),
|
||||
status: (b as any).status,
|
||||
parties: partiesPreview,
|
||||
createdAt: (b as any).createdAt,
|
||||
updatedAt: (b as any).updatedAt,
|
||||
};
|
||||
prev.parties = prev.parties ?? partiesPreview;
|
||||
prev.createdAt = prev.createdAt ?? (b as any).createdAt;
|
||||
prev.updatedAt = (b as any).updatedAt ?? prev.updatedAt;
|
||||
byPublicId.set(key, prev);
|
||||
}
|
||||
|
||||
for (const c of claimFiles) {
|
||||
const key = String((c as any).publicId || (c as any)._id || "");
|
||||
if (!key) continue;
|
||||
const prev = byPublicId.get(key) ?? { publicId: key };
|
||||
const claimPartiesPreview = this.buildPartiesPreview((c as any)?.snapshot?.parties);
|
||||
prev.fileType = prev.fileType ?? (c as any)?.snapshot?.accident?.type;
|
||||
prev.claim = {
|
||||
requestId: (c as any)?._id?.toString?.() || String((c as any)?._id || ""),
|
||||
requestNo: (c as any).requestNo || String((c as any).requestNumber || ""),
|
||||
status: (c as any).status,
|
||||
claimStatus: (c as any).claimStatus,
|
||||
currentStep: (c as any).currentStep,
|
||||
createdAt: (c as any).createdAt,
|
||||
updatedAt: (c as any).updatedAt,
|
||||
};
|
||||
prev.parties = prev.parties ?? claimPartiesPreview;
|
||||
prev.createdAt = prev.createdAt ?? (c as any).createdAt;
|
||||
prev.updatedAt = (c as any).updatedAt ?? prev.updatedAt;
|
||||
byPublicId.set(key, prev);
|
||||
}
|
||||
|
||||
const files = Array.from(byPublicId.values())
|
||||
.map((f) => ({
|
||||
publicId: f.publicId,
|
||||
fileType: f.fileType,
|
||||
hasClaim: !!f.claim,
|
||||
parties: f.parties,
|
||||
blame: f.blame,
|
||||
claim: f.claim,
|
||||
createdAt: f.createdAt,
|
||||
updatedAt: f.updatedAt,
|
||||
}))
|
||||
.sort((a, b) => {
|
||||
const at = a.updatedAt ? new Date(a.updatedAt).getTime() : 0;
|
||||
const bt = b.updatedAt ? new Date(b.updatedAt).getTime() : 0;
|
||||
return bt - at;
|
||||
});
|
||||
|
||||
return {
|
||||
total: files.length,
|
||||
files,
|
||||
};
|
||||
}
|
||||
|
||||
async retrieveFileDetailsByPublicId(insurerId: string, publicId: string) {
|
||||
if (!publicId?.trim()) {
|
||||
throw new BadRequestException("publicId is required");
|
||||
}
|
||||
|
||||
const id = this.getClientId(insurerId);
|
||||
const [blameFiles, claimFiles] = await Promise.all([
|
||||
this.getClientBlameFiles(id),
|
||||
this.getClientClaimFiles(id),
|
||||
]);
|
||||
|
||||
const blame = blameFiles.find((b) => String((b as any).publicId) === publicId);
|
||||
const claim = claimFiles.find((c) => String((c as any).publicId) === publicId);
|
||||
|
||||
if (!blame && !claim) {
|
||||
throw new NotFoundException("File not found for this publicId");
|
||||
}
|
||||
|
||||
const parties = Array.isArray((blame as any)?.parties) ? (blame as any).parties : [];
|
||||
const firstParty = parties.find((p: any) => p?.role === "FIRST");
|
||||
const secondParty = parties.find((p: any) => p?.role === "SECOND");
|
||||
|
||||
const overview = {
|
||||
publicId,
|
||||
requestNo:
|
||||
(blame as any)?.requestNo ||
|
||||
(claim as any)?.requestNo ||
|
||||
(blame as any)?.requestNumber ||
|
||||
(claim as any)?.requestNumber,
|
||||
type: (blame as any)?.type,
|
||||
hasClaim: !!claim,
|
||||
blameStatus: (blame as any)?.status,
|
||||
claimStatus: (claim as any)?.status,
|
||||
claimReviewStatus: (claim as any)?.claimStatus,
|
||||
createdAt: (blame as any)?.createdAt ?? (claim as any)?.createdAt,
|
||||
updatedAt: (claim as any)?.updatedAt ?? (blame as any)?.updatedAt,
|
||||
};
|
||||
|
||||
const blameDetails = blame
|
||||
? {
|
||||
requestId:
|
||||
(blame as any)?._id?.toString?.() || String((blame as any)?._id || ""),
|
||||
requestNo:
|
||||
(blame as any).requestNo || String((blame as any).requestNumber || ""),
|
||||
status: (blame as any).status,
|
||||
blameStatus: (blame as any).blameStatus,
|
||||
workflow: (blame as any).workflow,
|
||||
parties: {
|
||||
first: firstParty
|
||||
? {
|
||||
fullName: firstParty?.person?.fullName,
|
||||
phoneNumber: firstParty?.person?.phoneNumber,
|
||||
role: firstParty?.role,
|
||||
vehicle: firstParty?.vehicle,
|
||||
}
|
||||
: undefined,
|
||||
second: secondParty
|
||||
? {
|
||||
fullName: secondParty?.person?.fullName,
|
||||
phoneNumber: secondParty?.person?.phoneNumber,
|
||||
role: secondParty?.role,
|
||||
vehicle: secondParty?.vehicle,
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
expert: (blame as any).expert
|
||||
? {
|
||||
assignedExpertId: (blame as any).expert?.assignedExpertId,
|
||||
decision: (blame as any).expert?.decision,
|
||||
resend: (blame as any).expert?.resend,
|
||||
rating: (blame as any).expert?.rating,
|
||||
}
|
||||
: undefined,
|
||||
createdAt: (blame as any).createdAt,
|
||||
updatedAt: (blame as any).updatedAt,
|
||||
}
|
||||
: undefined;
|
||||
|
||||
// Keep claim section claim-specific to avoid duplicating shared data already in blame/overview.
|
||||
const claimDetails = claim
|
||||
? {
|
||||
requestId:
|
||||
(claim as any)?._id?.toString?.() || String((claim as any)?._id || ""),
|
||||
requestNo:
|
||||
(claim as any).requestNo || String((claim as any).requestNumber || ""),
|
||||
status: (claim as any).status,
|
||||
claimStatus: (claim as any).claimStatus,
|
||||
workflow: {
|
||||
currentStep: (claim as any).currentStep,
|
||||
nextStep: (claim as any).nextStep,
|
||||
},
|
||||
evaluation: {
|
||||
damageExpertReply: (claim as any).damageExpertReply,
|
||||
damageExpertReplyFinal: (claim as any).damageExpertReplyFinal,
|
||||
damageExpertResend: (claim as any).damageExpertResend,
|
||||
objection: (claim as any).objection,
|
||||
priceDrop: (claim as any).priceDrop,
|
||||
visitLocation: (claim as any).visitLocation,
|
||||
},
|
||||
userResendDocuments: (claim as any).userResendDocuments,
|
||||
userRating: (claim as any).userRating,
|
||||
insurerRating: (claim as any).rating,
|
||||
createdAt: (claim as any).createdAt,
|
||||
updatedAt: (claim as any).updatedAt,
|
||||
}
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
overview,
|
||||
blame: blameDetails,
|
||||
claim: claimDetails,
|
||||
};
|
||||
}
|
||||
|
||||
async addBranch(clientKey: string, branchDto: CreateBranchDto) {
|
||||
|
||||
Reference in New Issue
Block a user