Fixed legacy requestedCounts methods and statistics + claimLink address

This commit is contained in:
SepehrYahyaee
2026-04-27 15:29:44 +03:30
parent 362e02ddc4
commit c2f996cc28
17 changed files with 441 additions and 394 deletions

View File

@@ -18,12 +18,15 @@ import { FileRating } from "src/request-management/entities/schema/request-manag
import { CaseStatus } from "src/Types&Enums/blame-request-management/caseStatus.enum";
import { DamageExpertDbService } from "src/users/entities/db-service/damage-expert.db.service";
import { ExpertDbService } from "src/users/entities/db-service/expert.db.service";
import { ExpertFileActivityDbService } from "src/users/entities/db-service/expert-file-activity.db.service";
import { ExpertFileActivityType } from "src/users/entities/schema/expert-file-activity.schema";
@Injectable()
export class ExpertInsurerService {
constructor(
private readonly expertDbService: ExpertDbService,
private readonly damageExpertDbService: DamageExpertDbService,
private readonly expertFileActivityDbService: ExpertFileActivityDbService,
private readonly blameRequestDbService: BlameRequestDbService,
private readonly claimCaseDbService: ClaimCaseDbService,
private readonly branchDbService: BranchDbService,
@@ -37,6 +40,43 @@ export class ExpertInsurerService {
return new Types.ObjectId(raw);
}
private async buildExpertActivityStatsMap(
tenantId: Types.ObjectId,
expertIds: string[],
): Promise<Record<string, { totalHandled: number; totalChecked: number }>> {
const events = await this.expertFileActivityDbService.findByTenantAndExperts(
tenantId,
expertIds,
);
const stateByExpertFile = new Map<string, { checked: boolean; handled: boolean }>();
for (const e of events) {
const key = `${String(e.expertId)}:${String(e.fileId)}`;
const prev = stateByExpertFile.get(key) ?? { checked: false, handled: false };
if (e.eventType === ExpertFileActivityType.CHECKED) {
if (!prev.handled) prev.checked = true;
} else if (e.eventType === ExpertFileActivityType.UNCHECKED) {
prev.checked = false;
} else if (e.eventType === ExpertFileActivityType.HANDLED) {
prev.handled = true;
prev.checked = false;
}
stateByExpertFile.set(key, prev);
}
const result: Record<string, { totalHandled: number; totalChecked: number }> = {};
for (const expertId of expertIds) {
result[expertId] = { totalHandled: 0, totalChecked: 0 };
}
for (const [key, st] of stateByExpertFile.entries()) {
const [expertId] = key.split(":");
if (!result[expertId]) result[expertId] = { totalHandled: 0, totalChecked: 0 };
if (st.handled) result[expertId].totalHandled += 1;
else if (st.checked) result[expertId].totalChecked += 1;
}
return result;
}
private parseObjectId(value: string, label: string): Types.ObjectId {
if (!Types.ObjectId.isValid(value)) {
throw new BadRequestException(`Invalid ${label}`);
@@ -141,6 +181,11 @@ export class ExpertInsurerService {
]);
const allExpertsRaw = [...experts, ...damageExperts];
const expertIds = allExpertsRaw.map((e) => String(e._id));
const expertActivityStatsMap = await this.buildExpertActivityStatsMap(
clientObjectId,
expertIds,
);
const expertTotalRatingsMap: Record<string, number[]> = {};
const expertRatingsByCategoryMap: Record<string, Record<string, number[]>> = {};
@@ -193,7 +238,10 @@ export class ExpertInsurerService {
fullName: `${expert.firstName} ${expert.lastName}`,
role: expert.role,
type: expert.userType,
requestStats: expert.requestStats,
requestStats: expertActivityStatsMap[expertIdStr] ?? {
totalHandled: 0,
totalChecked: 0,
},
createdAt: expert.createdAt,
overallAverageRating,
averageRatingsByCategory,