forked from Yara724/api
fix: harden claim review and inquiry workflows
Preserve damage history and current vehicle price, restore depreciation mapping, normalize inquiry/report output, and support resumable expert review with paginated case retrieval.
This commit is contained in:
@@ -101,7 +101,12 @@ import {
|
||||
ClaimListItemV2Dto,
|
||||
} from "./dto/my-claims-v2.dto";
|
||||
import { ListQueryV2Dto } from "src/common/dto/list-query-v2.dto";
|
||||
import { applyListQueryV2 } from "src/helpers/list-query-v2";
|
||||
import {
|
||||
applyListQueryV2,
|
||||
isInListDateRange,
|
||||
parseListDateRange,
|
||||
} from "src/helpers/list-query-v2";
|
||||
import { resolveUnifiedFileStatus } from "src/helpers/unified-file-status";
|
||||
import { partyPersonMatchesUser } from "src/helpers/iran-mobile";
|
||||
import {
|
||||
buildBlamePartyAccessOrConditions,
|
||||
@@ -206,6 +211,7 @@ import {
|
||||
partLookupKey,
|
||||
resolvePartCaptureIndex,
|
||||
} from "src/helpers/outer-damage-parts";
|
||||
import { serializeDamagedPartSelectionHistory } from "src/helpers/claim-damaged-part-audit";
|
||||
import { normalizeMoneyAmountString } from "src/utils/unicode-digits";
|
||||
import { PlateNormalizerService } from "src/utils/plate-normalizer/plate-normalizer.service";
|
||||
|
||||
@@ -12421,7 +12427,7 @@ export class ClaimRequestManagementService {
|
||||
blameIdsForList.length > 0
|
||||
? ((await this.blameRequestDbService.find(
|
||||
{ _id: { $in: blameIdsForList.map((id) => new Types.ObjectId(id)) } },
|
||||
{ lean: true, select: "type creationMethod" },
|
||||
{ lean: true, select: "type creationMethod status" },
|
||||
)) as any[])
|
||||
: [];
|
||||
const blameByIdForList = new Map<string, any>(
|
||||
@@ -12443,16 +12449,37 @@ export class ClaimRequestManagementService {
|
||||
blameRequestId: c.blameRequestId?.toString(),
|
||||
blameType: blameForItem?.type ?? undefined,
|
||||
creationMethod: blameForItem?.creationMethod ?? undefined,
|
||||
unifiedFileStatus: resolveUnifiedFileStatus({
|
||||
blameStatus: blameForItem?.status,
|
||||
claimStatus: c.status,
|
||||
}),
|
||||
};
|
||||
}) as ClaimListItemV2Dto[];
|
||||
|
||||
let filtered = list;
|
||||
if (query.unifiedStatus) {
|
||||
filtered = filtered.filter(
|
||||
(row) => row.unifiedFileStatus === query.unifiedStatus,
|
||||
);
|
||||
}
|
||||
const { fromDate, toDate } = parseListDateRange(
|
||||
query.startDate,
|
||||
query.endDate,
|
||||
);
|
||||
if (fromDate || toDate) {
|
||||
filtered = filtered.filter((row) =>
|
||||
isInListDateRange(row.createdAt, fromDate, toDate),
|
||||
);
|
||||
}
|
||||
|
||||
const paged = applyListQueryV2(
|
||||
list,
|
||||
filtered,
|
||||
{
|
||||
publicId: (r) => r.publicId,
|
||||
createdAt: (r) => r.createdAt,
|
||||
requestNo: (r) => r.requestNo,
|
||||
status: (r) => r.status,
|
||||
status: (r) => r.unifiedFileStatus ?? r.status,
|
||||
fileType: (r) => r.blameType,
|
||||
searchExtras: (r) =>
|
||||
[
|
||||
r.claimRequestId,
|
||||
@@ -12588,6 +12615,10 @@ export class ClaimRequestManagementService {
|
||||
catalogLikeKeyFromPart,
|
||||
buildFileLink,
|
||||
});
|
||||
const damagedPartsHistory = serializeDamagedPartSelectionHistory({
|
||||
history: (claim.damage as any)?.partSelectionHistory,
|
||||
currentSelectedParts: selectedNormDetails,
|
||||
});
|
||||
|
||||
const er = claim.evaluation?.damageExpertResend;
|
||||
const expertResend =
|
||||
@@ -12671,6 +12702,7 @@ export class ClaimRequestManagementService {
|
||||
: undefined,
|
||||
carAngles,
|
||||
damagedParts,
|
||||
damagedPartsHistory,
|
||||
expertResend,
|
||||
fanavaran: fanavaranClaimReferences(claim),
|
||||
evaluation: mappedEvaluation
|
||||
|
||||
@@ -83,7 +83,7 @@ export class ClaimRequestManagementV2Controller {
|
||||
@ApiOperation({
|
||||
summary: "Get My Claims (V2)",
|
||||
description:
|
||||
"Claims for the current user, or claims from blame files initiated by the current FIELD_EXPERT / REGISTRAR (LINK and IN_PERSON). Optional query: `search`, `sortBy`, `sortOrder`, `page`, `limit`.",
|
||||
"Claims for the current user, or claims from blame files initiated by the current FIELD_EXPERT / REGISTRAR (LINK and IN_PERSON). Optional query: `search`, `sortBy`, `sortOrder`, `page`, `limit`, `unifiedStatus`, `fileType`, `startDate`, `endDate`.",
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
|
||||
@@ -204,6 +204,33 @@ export class ClaimDetailsV2ResponseDto {
|
||||
fileName?: string;
|
||||
}>;
|
||||
|
||||
@ApiPropertyOptional({
|
||||
description:
|
||||
'Append-only expert damaged-part revisions. Removed rows retain their original capture URL.',
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
revisionId: { type: 'string' },
|
||||
changedAt: { type: 'string', format: 'date-time' },
|
||||
changedBy: { type: 'object' },
|
||||
removedParts: { type: 'array', items: { type: 'object' } },
|
||||
addedParts: { type: 'array', items: { type: 'object' } },
|
||||
},
|
||||
},
|
||||
})
|
||||
damagedPartsHistory?: Array<{
|
||||
revisionId: string;
|
||||
changedAt: Date | string;
|
||||
changedBy: {
|
||||
actorId: string;
|
||||
actorName?: string;
|
||||
actorType: string;
|
||||
};
|
||||
removedParts: Array<Record<string, unknown>>;
|
||||
addedParts: Array<Record<string, unknown>>;
|
||||
}>;
|
||||
|
||||
@ApiPropertyOptional({
|
||||
description:
|
||||
'Damage expert resend instructions and progress (when status is WAITING_FOR_USER_RESEND).',
|
||||
|
||||
@@ -40,6 +40,12 @@ export class ClaimListItemV2Dto {
|
||||
example: 'IN_PERSON',
|
||||
})
|
||||
creationMethod?: string;
|
||||
|
||||
@ApiPropertyOptional({
|
||||
description: 'Calculated combined blame and claim lifecycle status',
|
||||
example: 'WAITING_FOR_DAMAGE_EXPERT',
|
||||
})
|
||||
unifiedFileStatus?: string;
|
||||
}
|
||||
|
||||
export class GetMyClaimsV2ResponseDto {
|
||||
|
||||
@@ -18,6 +18,18 @@ export class ClaimDamageSelection {
|
||||
@Prop({ type: [String], default: [] })
|
||||
otherParts?: string[];
|
||||
|
||||
/**
|
||||
* Append-only expert edit revisions. Each revision preserves the prior
|
||||
* selection and capture metadata for removed parts before the live arrays
|
||||
* are replaced. Mixed keeps legacy/free-text part shapes readable.
|
||||
*/
|
||||
@Prop({ type: [MongooseSchema.Types.Mixed], default: [] })
|
||||
partSelectionHistory?: unknown[];
|
||||
|
||||
/** Parts introduced by an expert across revisions (used for origin labels). */
|
||||
@Prop({ type: [MongooseSchema.Types.Mixed], default: [] })
|
||||
expertAddedParts?: unknown[];
|
||||
|
||||
/**
|
||||
* Legacy fields - kept for backward compatibility
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user