forked from Yara724/api
YARA-914, YARA-923
This commit is contained in:
@@ -134,13 +134,16 @@ export class ClaimDetailV2ResponseDto {
|
||||
@ApiPropertyOptional({
|
||||
description:
|
||||
"Slice of `claim.evaluation` exposed to the damage expert. " +
|
||||
"`damageExpertReply` / `damageExpertReplyFinal` are returned only while " +
|
||||
"awaiting factor validation. `ownerInsurerApproval` and " +
|
||||
"`ownerPricedPartsApproval` are returned whenever they exist on the " +
|
||||
"claim — each carries `signLink` (resolved from `signDetailId`) so the " +
|
||||
"front-end can render the user signature directly. Likewise, " +
|
||||
"`damageExpertReply.userComment` / `damageExpertReplyFinal.userComment` " +
|
||||
"expose `signLink` when a user comment signature is present.",
|
||||
"`damageExpertReply` / `damageExpertReplyFinal` are returned whenever " +
|
||||
"present, regardless of the current claim status — historical assessment " +
|
||||
"data remains visible once the expert has submitted it. " +
|
||||
"`ownerInsurerApproval` and `ownerPricedPartsApproval` are returned " +
|
||||
"whenever they exist on the claim — each carries `signLink` (resolved " +
|
||||
"from `signDetailId`) so the front-end can render the user signature " +
|
||||
"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?: {
|
||||
damageExpertReply?: unknown;
|
||||
|
||||
@@ -541,6 +541,23 @@ export class ExpertClaimService {
|
||||
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(
|
||||
claim: any,
|
||||
blameById: Map<string, any>,
|
||||
@@ -554,10 +571,24 @@ export class ExpertClaimService {
|
||||
| undefined {
|
||||
const cv = claim?.vehicle;
|
||||
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 {
|
||||
carName: cv.carName,
|
||||
carModel: cv.carModel,
|
||||
carType: cv.carType,
|
||||
carName,
|
||||
carModel,
|
||||
carType,
|
||||
...((cv as any).plate ? { plate: (cv as any).plate } : {}),
|
||||
};
|
||||
}
|
||||
@@ -4801,6 +4832,24 @@ export class ExpertClaimService {
|
||||
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
|
||||
? this.blameFileContextForExpert(blameLean)
|
||||
: {};
|
||||
@@ -4853,7 +4902,11 @@ export class ExpertClaimService {
|
||||
let evaluationForApi: Record<string, unknown> | undefined;
|
||||
if (enrichedEvaluation) {
|
||||
evaluationForApi = {};
|
||||
if (isFactorValidationPending) {
|
||||
// damageExpertReply / damageExpertReplyFinal: include whenever present.
|
||||
// Previously these were gated on isFactorValidationPending, which hid the
|
||||
// expert assessment once the claim moved to user-side statuses such as
|
||||
// INSURER_REVIEW_AWAITING_OWNER_SIGN. Historical assessment data should
|
||||
// always be visible once submitted.
|
||||
if (enrichedEvaluation.damageExpertReply !== undefined) {
|
||||
evaluationForApi.damageExpertReply =
|
||||
enrichedEvaluation.damageExpertReply;
|
||||
@@ -4862,7 +4915,6 @@ export class ExpertClaimService {
|
||||
evaluationForApi.damageExpertReplyFinal =
|
||||
enrichedEvaluation.damageExpertReplyFinal;
|
||||
}
|
||||
}
|
||||
if (enrichedEvaluation.ownerInsurerApproval !== undefined) {
|
||||
evaluationForApi.ownerInsurerApproval =
|
||||
enrichedEvaluation.ownerInsurerApproval;
|
||||
@@ -4871,7 +4923,8 @@ export class ExpertClaimService {
|
||||
evaluationForApi.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;
|
||||
}
|
||||
if (Object.keys(evaluationForApi).length === 0) {
|
||||
|
||||
@@ -153,7 +153,7 @@ export class ExpertClaimV2Controller {
|
||||
@ApiOperation({
|
||||
summary: "Get claim request detail for damage expert",
|
||||
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" })
|
||||
async getClaimDetailV2(
|
||||
|
||||
Reference in New Issue
Block a user