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")
|
@Get("top-files")
|
||||||
async getTopFiles(@CurrentUser() insurer) {
|
async getTopFiles(@CurrentUser() insurer) {
|
||||||
return await this.expertInsurerService.getTopFilesForClient(
|
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 {
|
private getCombinedFileScore(file: any): number | null {
|
||||||
const insurerRating = file?.rating;
|
const insurerRating = file?.rating;
|
||||||
const userRating = file?.userRating;
|
const userRating = file?.userRating;
|
||||||
@@ -165,11 +178,6 @@ export class ExpertInsurerService {
|
|||||||
.filter((f) =>
|
.filter((f) =>
|
||||||
(f?.parties || []).some((p) => String(p?.person?.clientId || "") === idStr),
|
(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));
|
.map((f) => this.normalizeBlameCase(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,7 +185,7 @@ export class ExpertInsurerService {
|
|||||||
const all = (await this.claimCaseDbService.find({}, { lean: true })) as any[];
|
const all = (await this.claimCaseDbService.find({}, { lean: true })) as any[];
|
||||||
const idStr = String(clientObjectId);
|
const idStr = String(clientObjectId);
|
||||||
return all
|
return all
|
||||||
.filter((f) => String(f?.owner?.userClientKey || "") === idStr)
|
.filter((f) => claimCaseTouchesClient(f, idStr))
|
||||||
.map((f) => this.normalizeClaimCase(f));
|
.map((f) => this.normalizeClaimCase(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,7 +413,227 @@ export class ExpertInsurerService {
|
|||||||
this.getClientBlameFiles(id),
|
this.getClientBlameFiles(id),
|
||||||
this.getClientClaimFiles(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) {
|
async addBranch(clientKey: string, branchDto: CreateBranchDto) {
|
||||||
|
|||||||
Reference in New Issue
Block a user