1
0
forked from Yara724/api
This commit is contained in:
SepehrYahyaee
2026-05-09 12:09:17 +03:30
parent c1a54baaf0
commit 9e2cec5bc3
5 changed files with 295 additions and 5 deletions

View File

@@ -1207,12 +1207,66 @@ export class ExpertInsurerService {
const newBranch = await this.branchDbService.create({
...branchDto,
isActive: branchDto.isActive ?? true,
activityStartDate: branchDto.activityStartDate
? new Date(branchDto.activityStartDate)
: undefined,
clientKey: clientId,
});
return newBranch;
}
private parseOptionalBoolean(value?: string): boolean | undefined {
if (value == null || value === "") return undefined;
const normalized = String(value).trim().toLowerCase();
if (["true", "1", "yes"].includes(normalized)) return true;
if (["false", "0", "no"].includes(normalized)) return false;
throw new BadRequestException("Invalid boolean value for 'isActive'");
}
private buildHandlingBranchStatusSets() {
const blameInHandling = new Set<string>([
CaseStatus.OPEN,
CaseStatus.WAITING_FOR_SECOND_PARTY,
CaseStatus.WAITING_FOR_EXPERT,
CaseStatus.WAITING_FOR_DOCUMENT_RESEND,
CaseStatus.WAITING_FOR_SIGNATURES,
]);
const claimInHandling = new Set<string>([
ClaimCaseStatus.CREATED,
ClaimCaseStatus.SELECTING_OUTER_PARTS,
ClaimCaseStatus.SELECTING_OTHER_PARTS,
ClaimCaseStatus.UPLOADING_REQUIRED_DOCUMENTS,
ClaimCaseStatus.CAPTURING_PART_DAMAGES,
ClaimCaseStatus.WAITING_FOR_USER_RESEND,
ClaimCaseStatus.WAITING_FOR_DAMAGE_EXPERT,
ClaimCaseStatus.EXPERT_REVIEWING,
ClaimCaseStatus.WAITING_FOR_INSURER_APPROVAL,
ClaimCaseStatus.INSURER_REVIEW_AWAITING_OWNER_SIGN,
ClaimCaseStatus.INSURER_REVIEW_MIXED_FACTORS_PENDING,
ClaimCaseStatus.OWNER_REPAIR_FACTOR_UPLOAD_PENDING,
ClaimCaseStatus.EXPERT_VALIDATING_REPAIR_FACTORS,
]);
return { blameInHandling, claimInHandling };
}
async setBranchActive(
clientKey: string,
branchId: string,
isActive: boolean,
) {
const clientId = this.getClientId(clientKey);
await this.assertBranchBelongsToClient(branchId, clientId);
const updated = await this.branchDbService.findByIdAndUpdate(branchId, {
$set: { isActive },
});
if (!updated) {
throw new NotFoundException("Branch not found");
}
return updated;
}
private async assertBranchBelongsToClient(
branchId: string,
clientId: Types.ObjectId,
@@ -1445,8 +1499,108 @@ export class ExpertInsurerService {
};
}
async retrieveInsuranceBranches(insuranceId: string) {
return this.branchDbService.findAll(insuranceId);
async retrieveInsuranceBranches(
insuranceId: string,
opts?: {
search?: string;
from?: string;
to?: string;
isActive?: string;
},
) {
const clientObjectId = this.getClientId(insuranceId);
const { fromDate, toDate } = this.parseDateRange(opts?.from, opts?.to);
const isActiveFilter = this.parseOptionalBoolean(opts?.isActive);
const branches = await this.branchDbService.findAllWithFilters(String(clientObjectId), {
search: opts?.search,
from: fromDate,
to: toDate,
isActive: isActiveFilter,
});
const branchIdSet = new Set(branches.map((b: any) => String(b._id)));
const ckFilter = this.clientKeyScopeFilter(clientObjectId);
const [experts, damageExperts, blameFiles, claimFiles] = await Promise.all([
this.expertDbService.findAll(ckFilter as never),
this.damageExpertDbService.findAll(ckFilter as never),
this.getClientBlameFiles(clientObjectId),
this.getClientClaimFiles(clientObjectId),
]);
const activeExpertsByBranch = new Map<string, Set<string>>();
const expertBranchById = new Map<string, string>();
const claimExpertBranchById = new Map<string, string>();
for (const e of experts as any[]) {
const bid = e?.branchId ? String(e.branchId) : "";
if (!bid || !branchIdSet.has(bid)) continue;
const eid = String(e?._id || "");
if (!eid) continue;
expertBranchById.set(eid, bid);
if (!activeExpertsByBranch.has(bid)) activeExpertsByBranch.set(bid, new Set());
activeExpertsByBranch.get(bid)!.add(eid);
}
for (const e of damageExperts as any[]) {
const bid = e?.branchId ? String(e.branchId) : "";
if (!bid || !branchIdSet.has(bid)) continue;
const eid = String(e?._id || "");
if (!eid) continue;
claimExpertBranchById.set(eid, bid);
if (!activeExpertsByBranch.has(bid)) activeExpertsByBranch.set(bid, new Set());
activeExpertsByBranch.get(bid)!.add(eid);
}
const completedByBranch = new Map<string, Set<string>>();
const handlingByBranch = new Map<string, Set<string>>();
const { blameInHandling, claimInHandling } = this.buildHandlingBranchStatusSets();
const addPublicId = (map: Map<string, Set<string>>, branchId: string, fileKey: string) => {
if (!map.has(branchId)) map.set(branchId, new Set());
map.get(branchId)!.add(fileKey);
};
for (const b of blameFiles as any[]) {
const expertId = String(b?.expert?.assignedExpertId || "");
if (!expertId) continue;
const bid = expertBranchById.get(expertId);
if (!bid) continue;
const fileKey = String(b?.publicId || b?._id || "");
if (!fileKey) continue;
const status = String(b?.status || "");
if (status === CaseStatus.COMPLETED) addPublicId(completedByBranch, bid, fileKey);
if (blameInHandling.has(status)) addPublicId(handlingByBranch, bid, fileKey);
}
for (const c of claimFiles as any[]) {
const expertId = String(this.claimDamageExpertActorId(c) || "");
if (!expertId) continue;
const bid = claimExpertBranchById.get(expertId);
if (!bid) continue;
const fileKey = String(c?.publicId || c?._id || "");
if (!fileKey) continue;
const status = String(c?.status || "");
if (status === ClaimCaseStatus.COMPLETED) addPublicId(completedByBranch, bid, fileKey);
if (claimInHandling.has(status)) addPublicId(handlingByBranch, bid, fileKey);
}
const list = branches.map((branch: any) => {
const bid = String(branch._id);
return {
...branch,
totalActiveExperts: activeExpertsByBranch.get(bid)?.size ?? 0,
totalFinishedFiles: completedByBranch.get(bid)?.size ?? 0,
totalFilesInHandling: handlingByBranch.get(bid)?.size ?? 0,
};
});
return {
total: list.length,
filters: {
search: opts?.search ?? null,
from: fromDate ?? null,
to: toDate ?? null,
isActive: isActiveFilter ?? null,
},
branches: list,
};
}
private parseDateRange(from?: string, to?: string) {