This commit is contained in:
SepehrYahyaee
2026-04-27 17:03:29 +03:30
parent c2f996cc28
commit e90f8dc33c
5 changed files with 288 additions and 28 deletions

View File

@@ -84,6 +84,11 @@ import {
normalizeResendPartKeys,
partKeyAllowedForExpertResend,
} from "src/helpers/claim-expert-resend";
import {
ClaimVehicleTypeV2,
OUTER_PARTS_BY_CAR_TYPE,
OuterPartCatalogItem,
} from "src/static/outer-car-parts-catalog";
@Injectable()
export class ClaimRequestManagementService {
@@ -132,6 +137,26 @@ export class ClaimRequestManagementService {
return new Promise((resolve) => setTimeout(resolve, ms));
}
getOuterPartsCatalogV2(carType?: ClaimVehicleTypeV2): OuterPartCatalogItem[] {
if (carType) {
return (OUTER_PARTS_BY_CAR_TYPE[carType] || []).map((p) => ({
...p,
carType,
}));
}
const out: OuterPartCatalogItem[] = [];
for (const [type, items] of Object.entries(OUTER_PARTS_BY_CAR_TYPE)) {
const t = type as ClaimVehicleTypeV2;
for (const p of items) {
out.push({ ...p, carType: t });
}
}
return out.sort((a, b) => {
if (a.carType === b.carType) return a.id - b.id;
return String(a.carType).localeCompare(String(b.carType));
});
}
private userDamageDetail(blRequest: RequestManagementModel) {
const { firstPartyDetails: first, secondPartyDetails: second } = blRequest;
switch (blRequest.expertSubmitReply.guiltyUserId) {
@@ -3734,8 +3759,37 @@ export class ClaimRequestManagementService {
);
}
// 5. Convert selected parts to storage format (simple array of strings)
// Backward compatibility: some clients may still send legacy `carPartDamage` object.
// 5. Validate by selected car type and resolve selected parts by ids/keys
const selectedCarType = (body as any)?.carType as
| ClaimVehicleTypeV2
| undefined;
if (!selectedCarType || !OUTER_PARTS_BY_CAR_TYPE[selectedCarType]) {
throw new BadRequestException(
"Vehicle type is required before selecting outer parts.",
);
}
const catalog = OUTER_PARTS_BY_CAR_TYPE[selectedCarType];
const byId = new Map<number, OuterPartCatalogItem>(catalog.map((p) => [p.id, p]));
const byKey = new Map<string, OuterPartCatalogItem>(catalog.map((p) => [p.key, p]));
const selectedFromIds: OuterPartCatalogItem[] = [];
if (
Array.isArray((body as any)?.selectedPartIds) &&
(body as any).selectedPartIds.length > 0
) {
for (const id of (body as any).selectedPartIds as number[]) {
const item = byId.get(id);
if (!item) {
throw new BadRequestException(
`Invalid outer part id for ${selectedCarType}: ${id}`,
);
}
selectedFromIds.push(item);
}
}
// Backward compatibility with selectedParts + legacy carPartDamage
let selectedParts = Array.isArray((body as any)?.selectedParts)
? ((body as any).selectedParts as string[])
: [];
@@ -3747,17 +3801,52 @@ export class ClaimRequestManagementService {
(body as any).carPartDamage as CarDamagePartDto,
);
}
if (selectedParts.length === 0) {
const selectedFromKeys: OuterPartCatalogItem[] = [];
for (const key of selectedParts) {
const item = byKey.get(key);
if (!item) {
throw new BadRequestException(
`Invalid outer part key for ${selectedCarType}: ${key}`,
);
}
selectedFromKeys.push(item);
}
const selectedItems =
selectedFromIds.length > 0 ? selectedFromIds : selectedFromKeys;
if (selectedItems.length === 0) {
throw new BadRequestException(
"selectedParts is required and must contain at least one item",
"selectedPartIds or selectedParts is required and must contain at least one item",
);
}
// At most two non-top sides allowed
const sideSet = new Set(
selectedItems
.map((p) => p.side)
.filter((s) => s !== "top"),
);
if (sideSet.size > 2) {
throw new BadRequestException(
`At most two of left/right/front/back can be selected. Selected: ${[...sideSet].join(", ")}`,
);
}
selectedParts = selectedItems.map((p) => p.key);
const selectedPartIds = selectedItems.map((p) => p.id);
const selectedOuterParts = selectedItems.map((p) => ({
id: p.id,
key: p.key,
side: p.side,
}));
// 6. Update claim case with selected parts and move to next step
const updatedClaim = await this.claimCaseDbService.findByIdAndUpdate(
claimRequestId,
{
'damage.selectedParts': selectedParts,
'damage.selectedOuterParts': selectedOuterParts,
'vehicle.carType': selectedCarType,
'status': ClaimCaseStatus.SELECTING_OTHER_PARTS,
'workflow.currentStep': ClaimWorkflowStep.SELECT_OTHER_PARTS,
'workflow.nextStep': ClaimWorkflowStep.CAPTURE_PART_DAMAGES,
@@ -3774,6 +3863,8 @@ export class ClaimRequestManagementService {
metadata: {
stepKey: ClaimWorkflowStep.SELECT_OUTER_PARTS,
selectedParts: selectedParts,
selectedPartIds,
carType: selectedCarType,
partsCount: selectedParts?.length,
description: `User selected ${selectedParts?.length} damaged outer parts`,
},
@@ -3795,6 +3886,7 @@ export class ClaimRequestManagementService {
claimRequestId: updatedClaim._id.toString(),
publicId: updatedClaim.publicId,
selectedParts: selectedParts,
selectedPartIds,
currentStep: ClaimWorkflowStep.SELECT_OTHER_PARTS,
nextStep: ClaimWorkflowStep.CAPTURE_PART_DAMAGES,
message: 'Outer parts selected successfully. Please proceed to select other parts and provide bank information.',