Merge pull request 'fix claim validation and expert branch scoping' (#335) from s.yahyaee/yara724-api:main into main

Reviewed-on: Yara724/api#335
This commit is contained in:
2026-09-20 15:03:22 +03:30
13 changed files with 640 additions and 29 deletions

View File

@@ -1226,6 +1226,7 @@ export class ClaimRequestManagementService {
claimRequestId: string,
expert: any,
dto: {
selectedPartIds?: number[];
carPartDamage?: CarDamagePartDto;
sheba?: string;
nationalCodeOfInsurer?: string;
@@ -1262,12 +1263,34 @@ export class ClaimRequestManagementService {
);
}
if (dto.carPartDamage) {
if (dto.selectedPartIds?.length || dto.carPartDamage) {
if (claim.carPartDamage && (claim.carPartDamage as any[]).length > 0) {
throw new BadRequestException("Car part damage is already set.");
}
this.assertCarPartDamageAtMostTwoOfFourSides(dto.carPartDamage);
const trueItems = this.findTrueItems(dto.carPartDamage);
let trueItems: Array<Record<string, unknown>>;
if (dto.selectedPartIds?.length) {
const liveCatalog = await this.getLiveFanavaranCatalogItems();
const byId = new Map<number, OuterPartCatalogItem>(
liveCatalog.map((part) => [part.id, part]),
);
trueItems = dto.selectedPartIds.map((id) => {
const item = byId.get(id);
if (!item) {
throw new BadRequestException(
`Invalid outer part id: ${id}. Use GET outer-parts-catalog to see valid IDs.`,
);
}
return {
side: item.side || "carDamage",
part: item.titleFa,
id: item.id,
label_fa: item.titleFa,
};
});
} else {
this.assertCarPartDamageAtMostTwoOfFourSides(dto.carPartDamage!);
trueItems = this.findTrueItems(dto.carPartDamage!);
}
const claimDoc = (await this.claimDbService.findOne(
claimRequestId,
)) as any;
@@ -1302,6 +1325,7 @@ export class ClaimRequestManagementService {
claimRequestId: string,
expert: any,
dto: {
selectedPartIds?: number[];
carPartDamage?: CarDamagePartDto;
sheba?: string;
nationalCodeOfInsurer?: string;
@@ -1313,7 +1337,7 @@ export class ClaimRequestManagementService {
let working = claimCase;
if (dto.carPartDamage) {
if (dto.selectedPartIds?.length || dto.carPartDamage) {
if (
working.workflow?.currentStep !== ClaimWorkflowStep.SELECT_OUTER_PARTS
) {
@@ -1327,20 +1351,41 @@ export class ClaimRequestManagementService {
) {
throw new BadRequestException("Car part damage is already set.");
}
this.assertCarPartDamageAtMostTwoOfFourSides(dto.carPartDamage);
const selectedSlugStrings = this.carDamagePartDtoToOuterPartSlugs(
dto.carPartDamage,
);
if (!selectedSlugStrings.length) {
throw new BadRequestException(
"No outer damaged parts could be derived from carPartDamage. Check part selections.",
let selectedPartObjs: DamageSelectedPartV2[];
if (dto.selectedPartIds?.length) {
const liveCatalog = await this.getLiveFanavaranCatalogItems();
const byId = new Map<number, OuterPartCatalogItem>(
liveCatalog.map((part) => [part.id, part]),
);
const selectedItems = dto.selectedPartIds.map((id) => {
const item = byId.get(id);
if (!item) {
throw new BadRequestException(
`Invalid outer part id: ${id}. Use GET outer-parts-catalog to see valid IDs.`,
);
}
return item;
});
selectedPartObjs = selectedItems.map((part) =>
catalogItemToSelectedPart(part, liveCatalog),
);
} else {
// Backward compatibility for older expert-panel clients.
this.assertCarPartDamageAtMostTwoOfFourSides(dto.carPartDamage!);
const selectedSlugStrings = this.carDamagePartDtoToOuterPartSlugs(
dto.carPartDamage!,
);
if (!selectedSlugStrings.length) {
throw new BadRequestException(
"No outer damaged parts could be derived from carPartDamage. Check part selections.",
);
}
selectedPartObjs = normalizeDamageSelectedParts(
selectedSlugStrings,
working.vehicle?.carType as ClaimVehicleTypeV2 | undefined,
undefined,
);
}
const selectedPartObjs = normalizeDamageSelectedParts(
selectedSlugStrings,
working.vehicle?.carType as ClaimVehicleTypeV2 | undefined,
undefined,
);
const damagedPartsStubs = selectedPartObjs.map((p) => ({
id: p.id ?? undefined,
name: p.name,
@@ -9302,6 +9347,9 @@ export class ClaimRequestManagementService {
blameRequestId: new Types.ObjectId(blameRequestId),
blameRequestNo: blameRequest.requestNo,
initiatedByFieldExpertId: new Types.ObjectId(expert.sub),
...((blameRequest as any).branchId
? { branchId: new Types.ObjectId(String((blameRequest as any).branchId)) }
: {}),
status: ClaimCaseStatus.SELECTING_OUTER_PARTS,
claimStatus: ClaimStatus.PENDING,
inquiries: (blameRequest as any).inquiries ?? {},