forked from Yara724/api
YARA-914, YARA-923
This commit is contained in:
@@ -134,13 +134,16 @@ export class ClaimDetailV2ResponseDto {
|
|||||||
@ApiPropertyOptional({
|
@ApiPropertyOptional({
|
||||||
description:
|
description:
|
||||||
"Slice of `claim.evaluation` exposed to the damage expert. " +
|
"Slice of `claim.evaluation` exposed to the damage expert. " +
|
||||||
"`damageExpertReply` / `damageExpertReplyFinal` are returned only while " +
|
"`damageExpertReply` / `damageExpertReplyFinal` are returned whenever " +
|
||||||
"awaiting factor validation. `ownerInsurerApproval` and " +
|
"present, regardless of the current claim status — historical assessment " +
|
||||||
"`ownerPricedPartsApproval` are returned whenever they exist on the " +
|
"data remains visible once the expert has submitted it. " +
|
||||||
"claim — each carries `signLink` (resolved from `signDetailId`) so the " +
|
"`ownerInsurerApproval` and `ownerPricedPartsApproval` are returned " +
|
||||||
"front-end can render the user signature directly. Likewise, " +
|
"whenever they exist on the claim — each carries `signLink` (resolved " +
|
||||||
"`damageExpertReply.userComment` / `damageExpertReplyFinal.userComment` " +
|
"from `signDetailId`) so the front-end can render the user signature " +
|
||||||
"expose `signLink` when a user comment signature is present.",
|
"directly. Likewise, `damageExpertReply.userComment` / " +
|
||||||
|
"`damageExpertReplyFinal.userComment` expose `signLink` when a user " +
|
||||||
|
"comment signature is present. `priceDrop` is included whenever it " +
|
||||||
|
"has been saved, not only during the expert review phase.",
|
||||||
})
|
})
|
||||||
evaluation?: {
|
evaluation?: {
|
||||||
damageExpertReply?: unknown;
|
damageExpertReply?: unknown;
|
||||||
|
|||||||
@@ -541,6 +541,23 @@ export class ExpertClaimService {
|
|||||||
return this.expertVehicleFromPartyVehicle(party?.vehicle);
|
return this.expertVehicleFromPartyVehicle(party?.vehicle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Extract car name / model from the inquiry snapshot embedded on the claim. */
|
||||||
|
private vehicleNamesFromClaimInquiries(claim: any): {
|
||||||
|
carName?: string;
|
||||||
|
carModel?: string;
|
||||||
|
} {
|
||||||
|
// Claim copies inquiries from blame at creation time.
|
||||||
|
// Try thirdParty first, then carBody.
|
||||||
|
const mapped =
|
||||||
|
claim?.inquiries?.thirdParty?.data?.FIRST?.mapped ??
|
||||||
|
claim?.inquiries?.carBody?.data?.FIRST?.mapped ??
|
||||||
|
{};
|
||||||
|
const carName: string | undefined =
|
||||||
|
mapped.MapTypNam || mapped.SystemField || undefined;
|
||||||
|
const carModel: string | undefined = mapped.TypeField || undefined;
|
||||||
|
return { carName, carModel };
|
||||||
|
}
|
||||||
|
|
||||||
private vehicleForExpertFromClaimAndBlameMap(
|
private vehicleForExpertFromClaimAndBlameMap(
|
||||||
claim: any,
|
claim: any,
|
||||||
blameById: Map<string, any>,
|
blameById: Map<string, any>,
|
||||||
@@ -554,10 +571,24 @@ export class ExpertClaimService {
|
|||||||
| undefined {
|
| undefined {
|
||||||
const cv = claim?.vehicle;
|
const cv = claim?.vehicle;
|
||||||
if (cv && (cv.carName || cv.carModel || cv.carType || (cv as any).plate)) {
|
if (cv && (cv.carName || cv.carModel || cv.carType || (cv as any).plate)) {
|
||||||
|
const carType: string | undefined = cv.carType;
|
||||||
|
// carName/carModel that match the enum value (e.g. "sedan") are invalid —
|
||||||
|
// the expert may have accidentally copied the carType value into those fields.
|
||||||
|
// Fall back to the inquiry snapshot for the real brand / variant strings.
|
||||||
|
let carName: string | undefined = cv.carName;
|
||||||
|
let carModel: string | undefined = cv.carModel;
|
||||||
|
if (
|
||||||
|
(!carName || carName === carType) ||
|
||||||
|
(!carModel || carModel === carType)
|
||||||
|
) {
|
||||||
|
const fromInquiry = this.vehicleNamesFromClaimInquiries(claim);
|
||||||
|
if (!carName || carName === carType) carName = fromInquiry.carName;
|
||||||
|
if (!carModel || carModel === carType) carModel = fromInquiry.carModel;
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
carName: cv.carName,
|
carName,
|
||||||
carModel: cv.carModel,
|
carModel,
|
||||||
carType: cv.carType,
|
carType,
|
||||||
...((cv as any).plate ? { plate: (cv as any).plate } : {}),
|
...((cv as any).plate ? { plate: (cv as any).plate } : {}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -4801,6 +4832,24 @@ export class ExpertClaimService {
|
|||||||
if (fromBlame) vehiclePayload = fromBlame;
|
if (fromBlame) vehiclePayload = fromBlame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Patch up carName/carModel when they equal carType (invalid — expert copied the enum value).
|
||||||
|
if (vehiclePayload) {
|
||||||
|
const carType: string | undefined = vehiclePayload.carType;
|
||||||
|
if (
|
||||||
|
carType &&
|
||||||
|
((!vehiclePayload.carName || vehiclePayload.carName === carType) ||
|
||||||
|
(!vehiclePayload.carModel || vehiclePayload.carModel === carType))
|
||||||
|
) {
|
||||||
|
const fromInquiry = this.vehicleNamesFromClaimInquiries(claim);
|
||||||
|
if (!vehiclePayload.carName || vehiclePayload.carName === carType) {
|
||||||
|
vehiclePayload = { ...vehiclePayload, carName: fromInquiry.carName };
|
||||||
|
}
|
||||||
|
if (!vehiclePayload.carModel || vehiclePayload.carModel === carType) {
|
||||||
|
vehiclePayload = { ...vehiclePayload, carModel: fromInquiry.carModel };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const blameFileContext = blameLean
|
const blameFileContext = blameLean
|
||||||
? this.blameFileContextForExpert(blameLean)
|
? this.blameFileContextForExpert(blameLean)
|
||||||
: {};
|
: {};
|
||||||
@@ -4853,15 +4902,18 @@ export class ExpertClaimService {
|
|||||||
let evaluationForApi: Record<string, unknown> | undefined;
|
let evaluationForApi: Record<string, unknown> | undefined;
|
||||||
if (enrichedEvaluation) {
|
if (enrichedEvaluation) {
|
||||||
evaluationForApi = {};
|
evaluationForApi = {};
|
||||||
if (isFactorValidationPending) {
|
// damageExpertReply / damageExpertReplyFinal: include whenever present.
|
||||||
if (enrichedEvaluation.damageExpertReply !== undefined) {
|
// Previously these were gated on isFactorValidationPending, which hid the
|
||||||
evaluationForApi.damageExpertReply =
|
// expert assessment once the claim moved to user-side statuses such as
|
||||||
enrichedEvaluation.damageExpertReply;
|
// INSURER_REVIEW_AWAITING_OWNER_SIGN. Historical assessment data should
|
||||||
}
|
// always be visible once submitted.
|
||||||
if (enrichedEvaluation.damageExpertReplyFinal !== undefined) {
|
if (enrichedEvaluation.damageExpertReply !== undefined) {
|
||||||
evaluationForApi.damageExpertReplyFinal =
|
evaluationForApi.damageExpertReply =
|
||||||
enrichedEvaluation.damageExpertReplyFinal;
|
enrichedEvaluation.damageExpertReply;
|
||||||
}
|
}
|
||||||
|
if (enrichedEvaluation.damageExpertReplyFinal !== undefined) {
|
||||||
|
evaluationForApi.damageExpertReplyFinal =
|
||||||
|
enrichedEvaluation.damageExpertReplyFinal;
|
||||||
}
|
}
|
||||||
if (enrichedEvaluation.ownerInsurerApproval !== undefined) {
|
if (enrichedEvaluation.ownerInsurerApproval !== undefined) {
|
||||||
evaluationForApi.ownerInsurerApproval =
|
evaluationForApi.ownerInsurerApproval =
|
||||||
@@ -4871,7 +4923,8 @@ export class ExpertClaimService {
|
|||||||
evaluationForApi.ownerPricedPartsApproval =
|
evaluationForApi.ownerPricedPartsApproval =
|
||||||
enrichedEvaluation.ownerPricedPartsApproval;
|
enrichedEvaluation.ownerPricedPartsApproval;
|
||||||
}
|
}
|
||||||
if (isDamageExpertPhase && enrichedEvaluation.priceDrop !== undefined) {
|
// priceDrop: include whenever present, not only during the expert phase.
|
||||||
|
if (enrichedEvaluation.priceDrop !== undefined) {
|
||||||
evaluationForApi.priceDrop = enrichedEvaluation.priceDrop;
|
evaluationForApi.priceDrop = enrichedEvaluation.priceDrop;
|
||||||
}
|
}
|
||||||
if (Object.keys(evaluationForApi).length === 0) {
|
if (Object.keys(evaluationForApi).length === 0) {
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ export class ExpertClaimV2Controller {
|
|||||||
@ApiOperation({
|
@ApiOperation({
|
||||||
summary: "Get claim request detail for damage expert",
|
summary: "Get claim request detail for damage expert",
|
||||||
description:
|
description:
|
||||||
"Returns full claim details including captured images, required documents, damage selections, `evaluation.priceDrop` during damage review, `videoCapture` (from claim-video-capture via media.videoCaptureId), and `blameCase` (linked blameCases document with party video/voice URLs like expert-blame detail). Allowed when status is WAITING_FOR_DAMAGE_EXPERT (if locked, only the locking expert) or when awaiting factor validation.",
|
"Returns full claim details including captured images, required documents, damage selections, `evaluation.priceDrop` (included whenever saved, regardless of current status), `videoCapture` (from claim-video-capture via media.videoCaptureId), and `blameCase` (linked blameCases document with party video/voice URLs like expert-blame detail). `evaluation.damageExpertReply` / `damageExpertReplyFinal` are always returned once submitted. Allowed when status is WAITING_FOR_DAMAGE_EXPERT (if locked, only the locking expert) or when awaiting factor validation.",
|
||||||
})
|
})
|
||||||
@ApiParam({ name: "claimRequestId" })
|
@ApiParam({ name: "claimRequestId" })
|
||||||
async getClaimDetailV2(
|
async getClaimDetailV2(
|
||||||
|
|||||||
Reference in New Issue
Block a user