forked from Yara724/api
396 lines
9.5 KiB
TypeScript
396 lines
9.5 KiB
TypeScript
import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose";
|
|
import { Types } from "mongoose";
|
|
import {
|
|
CarDetail,
|
|
RequestManagementModel,
|
|
} from "src/request-management/entities/schema/request-management.schema";
|
|
import { UserSignModel } from "src/request-management/entities/schema/sign.schema";
|
|
import { ReqClaimStatus } from "src/Types&Enums/claim-request-management/status.enum";
|
|
import { ClaimStepsEnum } from "src/Types&Enums/claim-request-management/steps.enum";
|
|
import { UserReplyEnum } from "src/Types&Enums/claim-request-management/userReply.enum";
|
|
import { AiImagesModel } from "./ai-image.schema";
|
|
import { CarGreenCardModel } from "./car-green-card.schema";
|
|
import {
|
|
CarDamagePartModel,
|
|
CarDamagePartOtherModel,
|
|
} from "./car-parts.schema";
|
|
import { ImageRequiredModel } from "./image-required.schema";
|
|
import { Plates } from "src/Types&Enums/plate.interface";
|
|
import { AddPlateDto } from "src/profile/dto/user/AddPlateDto";
|
|
import { FactorStatus } from "src/Types&Enums/claim-request-management/factor-status.enum";
|
|
import { DaghiOption } from "src/Types&Enums/claim-request-management/daghi-option.enum";
|
|
|
|
// main schema
|
|
export type ClaimRequestManagementDoc = ClaimRequestManagementModel & Document;
|
|
|
|
export class EffectedUserReply {
|
|
@Prop({ required: true, type: String })
|
|
reply?: UserReplyEnum;
|
|
|
|
@Prop({ required: true })
|
|
signDetail?: UserSignModel;
|
|
}
|
|
|
|
export class UserComment {
|
|
@Prop({ type: Boolean })
|
|
isAccept: boolean;
|
|
|
|
@Prop({ required: false })
|
|
signDetail?: Types.ObjectId;
|
|
}
|
|
|
|
export class DaghiDetails {
|
|
@Prop({ required: true, type: String, enum: DaghiOption })
|
|
option: DaghiOption;
|
|
|
|
@Prop({ required: false, type: String })
|
|
price?: string;
|
|
|
|
@Prop({ required: false, type: Types.ObjectId })
|
|
branchId?: Types.ObjectId;
|
|
}
|
|
|
|
export class PartsList {
|
|
@Prop({ required: true, type: String })
|
|
partId: string;
|
|
|
|
@Prop({ required: true, type: String })
|
|
carPartDamage: string;
|
|
|
|
@Prop({ required: true, type: String })
|
|
typeOfDamage: string;
|
|
|
|
@Prop({ required: true, type: String })
|
|
price: string;
|
|
|
|
@Prop({ required: true, type: String })
|
|
salary: string;
|
|
|
|
@Prop({ required: true, type: String })
|
|
totalPayment: string;
|
|
|
|
@Prop({ required: true, type: DaghiDetails })
|
|
daghi: DaghiDetails;
|
|
|
|
@Prop({ required: true, type: Boolean })
|
|
factorNeeded: boolean;
|
|
|
|
@Prop({ type: Types.ObjectId })
|
|
factorLink?: Types.ObjectId;
|
|
|
|
@Prop({ type: String, enum: FactorStatus, default: null })
|
|
factorStatus?: FactorStatus;
|
|
|
|
@Prop({ type: String, default: null })
|
|
rejectionReason?: string;
|
|
}
|
|
|
|
export class ActorDetail {
|
|
@Prop()
|
|
actorName: string;
|
|
|
|
@Prop()
|
|
actorId: string;
|
|
}
|
|
|
|
export class InPersonDocuments {
|
|
@Prop()
|
|
NationalCertificate: string;
|
|
|
|
@Prop()
|
|
CarCertificate: string;
|
|
|
|
@Prop()
|
|
DrivingLicense: string;
|
|
|
|
@Prop()
|
|
CarGreenCard: string;
|
|
}
|
|
|
|
export class SubmitReply {
|
|
@Prop({ required: true })
|
|
description: string;
|
|
|
|
@Prop({ required: true })
|
|
actorDetail: ActorDetail;
|
|
|
|
@Prop({ required: true, type: [PartsList] })
|
|
parts: PartsList[];
|
|
|
|
@Prop({ required: true, default: () => new Date() })
|
|
submitTime: Date;
|
|
|
|
@Prop()
|
|
userComment?: UserComment;
|
|
|
|
/** Damage expert profile at reply time (`damage-expert` collection). */
|
|
@Prop({ type: Object })
|
|
expertProfileSnapshot?: Record<string, string | undefined>;
|
|
}
|
|
|
|
export class ActorLockDetails {
|
|
@Prop({ type: String })
|
|
fullName?: string;
|
|
|
|
@Prop({ type: Types.ObjectId })
|
|
actorId?: Types.ObjectId;
|
|
|
|
/** Damage expert profile when lock was taken (`damage-expert` collection). */
|
|
@Prop({ type: Object })
|
|
expertProfileSnapshot?: Record<string, string | undefined>;
|
|
}
|
|
|
|
export class ResendCarPartsDto {
|
|
@Prop({ required: true })
|
|
partId: string;
|
|
|
|
@Prop({ required: true })
|
|
partName: string;
|
|
}
|
|
|
|
export class ClaimSubmitResend {
|
|
@Prop({ required: true })
|
|
resendDescription: string;
|
|
|
|
@Prop({ required: true, type: [InPersonDocuments] })
|
|
resendDocuments: InPersonDocuments[];
|
|
|
|
@Prop({ required: true })
|
|
resendCarParts: ResendCarPartsDto[];
|
|
|
|
/** Damage expert profile when resend was requested (`damage-expert` collection). */
|
|
@Prop({ type: Object })
|
|
expertProfileSnapshot?: Record<string, string | undefined>;
|
|
}
|
|
|
|
export class UserResendDocuments {
|
|
@Prop({ required: false })
|
|
documents: [];
|
|
|
|
@Prop({ required: false })
|
|
carParts: [];
|
|
}
|
|
|
|
export class UserObjection {
|
|
@Prop({ type: String, required: true })
|
|
partId: string;
|
|
|
|
@Prop({ type: String })
|
|
reason: string;
|
|
|
|
@Prop({ type: String })
|
|
partPrice: string;
|
|
|
|
@Prop({ type: String })
|
|
partSalary: string;
|
|
|
|
@Prop({ type: String })
|
|
typeOfDamage: string;
|
|
}
|
|
|
|
@Schema({ _id: false })
|
|
export class UserClaimRating {
|
|
// 1. سرعت پیشرفت پرونده (speed of progress)
|
|
@Prop({ type: Number, min: 0, max: 5, required: true })
|
|
progressSpeed: number;
|
|
|
|
// 2. سهولت ثبت پرونده (ease of registration)
|
|
@Prop({ type: Number, min: 0, max: 5, required: true })
|
|
registrationEase: number;
|
|
|
|
// 3. ارزیابی کلی (overall evaluation)
|
|
@Prop({ type: Number, min: 0, max: 5, required: true })
|
|
overallEvaluation: number;
|
|
|
|
// 4. متن رضایت یا عدم آن (optional text feedback)
|
|
@Prop({ type: String, required: false })
|
|
comment?: string;
|
|
|
|
@Prop({ type: Date, default: () => new Date() })
|
|
createdAt?: Date;
|
|
}
|
|
|
|
@Schema({ _id: false })
|
|
export class FileRating {
|
|
@Prop({ type: Number, min: 0, max: 5 })
|
|
collisionMethodAccuracy: number;
|
|
|
|
@Prop({ type: Number, min: 0, max: 5 })
|
|
evaluationTimeliness: number;
|
|
|
|
@Prop({ type: Number, min: 0, max: 5 })
|
|
accidentCauseAccuracy: number;
|
|
|
|
@Prop({ type: Number, min: 0, max: 5 })
|
|
guiltyVehicleIdentification: number;
|
|
|
|
@Prop({ type: Number, min: 0, max: 5 })
|
|
botRating: number;
|
|
}
|
|
|
|
export class PriceDrop {
|
|
@Prop({ type: Number })
|
|
total: number;
|
|
@Prop({ type: Number })
|
|
carPrice: number;
|
|
@Prop({ type: Number })
|
|
carModel: number;
|
|
@Prop({ type: [Number] })
|
|
carValue: number[];
|
|
@Prop({ type: Number })
|
|
sumOfSeverity: number;
|
|
}
|
|
|
|
@Schema({
|
|
collection: "claim-requests-management",
|
|
versionKey: false,
|
|
timestamps: true,
|
|
autoIndex: false,
|
|
})
|
|
export class ClaimRequestManagementModel {
|
|
readonly aiImage?: any;
|
|
constructor() {}
|
|
@Prop({ type: RequestManagementModel, unique: true })
|
|
blameFile: RequestManagementModel;
|
|
|
|
/**
|
|
* Human-friendly shared id across blame+claim (e.g. A14235).
|
|
* Copied from the source blame request.
|
|
*
|
|
* NOTE: `sparse` keeps existing documents without this field valid.
|
|
*/
|
|
@Prop({ type: String, unique: true, index: true, sparse: true, trim: true })
|
|
publicId?: string;
|
|
|
|
/**
|
|
* Explicit reference to the blame request id (in addition to embedded blameFile).
|
|
* This will be the preferred reference going forward.
|
|
*/
|
|
@Prop({ type: Types.ObjectId, index: true })
|
|
blameRequestId?: Types.ObjectId;
|
|
|
|
@Prop({ type: Number, default: 100 })
|
|
requestNumber?: number;
|
|
|
|
@Prop({ type: Types.ObjectId })
|
|
userClientKey?: Types.ObjectId;
|
|
|
|
@Prop({ type: Types.ObjectId })
|
|
userId: Types.ObjectId;
|
|
|
|
@Prop()
|
|
fullName: string;
|
|
|
|
@Prop()
|
|
carDetail: CarDetail;
|
|
|
|
@Prop({ type: AddPlateDto })
|
|
carPlate: Plates;
|
|
|
|
@Prop({})
|
|
claimStatus: ReqClaimStatus;
|
|
|
|
@Prop({})
|
|
steps: ClaimStepsEnum[];
|
|
|
|
@Prop({})
|
|
currentStep: ClaimStepsEnum;
|
|
|
|
@Prop({})
|
|
nextStep?: ClaimStepsEnum;
|
|
|
|
@Prop({ type: CarDamagePartModel })
|
|
carPartDamage?: CarDamagePartModel[];
|
|
|
|
@Prop({ type: CarDamagePartOtherModel })
|
|
otherParts?: CarDamagePartOtherModel[];
|
|
|
|
@Prop({ format: "string" })
|
|
sheba?: string;
|
|
|
|
@Prop({ format: "string" })
|
|
nationalCodeOfInsurer?: string;
|
|
|
|
@Prop({ type: CarGreenCardModel, required: false })
|
|
carGreenCard?: CarGreenCardModel;
|
|
|
|
@Prop({ type: ImageRequiredModel })
|
|
imageRequired?: ImageRequiredModel;
|
|
|
|
@Prop({ type: AiImagesModel })
|
|
aiImages?: AiImagesModel;
|
|
|
|
@Prop({ type: EffectedUserReply })
|
|
effectedUserReply?: EffectedUserReply;
|
|
|
|
@Prop()
|
|
lockFile?: boolean;
|
|
|
|
@Prop({ type: Date })
|
|
lockTime?: Date | string | number;
|
|
|
|
@Prop({ type: Date })
|
|
unlockTime?: Date | number;
|
|
|
|
@Prop()
|
|
actorLocked?: ActorLockDetails | null;
|
|
|
|
@Prop()
|
|
actorsChecker?: [];
|
|
|
|
@Prop({ required: false })
|
|
videoCaptureId?: Types.ObjectId;
|
|
|
|
@Prop({ required: false })
|
|
damageExpertReply?: SubmitReply | null;
|
|
|
|
@Prop({ required: false })
|
|
damageExpertReplyFinal?: SubmitReply | null;
|
|
|
|
@Prop({ required: false, type: ClaimSubmitResend })
|
|
damageExpertResend?: ClaimSubmitResend | null;
|
|
|
|
@Prop({ type: UserObjection, required: false })
|
|
objection?: UserObjection;
|
|
|
|
@Prop({ type: UserResendDocuments })
|
|
userResendDocuments?: UserResendDocuments;
|
|
|
|
@Prop({ type: PriceDrop, required: false })
|
|
priceDrop?: PriceDrop;
|
|
|
|
@Prop({ type: Map, of: Types.ObjectId, required: false })
|
|
requiredDocuments?: { [key: string]: Types.ObjectId };
|
|
|
|
createdAt: any;
|
|
updatedAt: any;
|
|
|
|
@Prop({ type: FileRating, required: false })
|
|
rating?: FileRating;
|
|
|
|
// User-facing satisfaction rating for this claim
|
|
@Prop({ type: UserClaimRating, required: false })
|
|
userRating?: UserClaimRating;
|
|
|
|
/** Latest damage expert profile when validating repair factors (V1). */
|
|
@Prop({ type: Object })
|
|
factorValidationExpertProfileSnapshot?: Record<string, string | undefined>;
|
|
|
|
/** Damage expert profile when in-person visit was requested (V1). */
|
|
@Prop({ type: Object })
|
|
damageExpertInPersonVisitProfileSnapshot?: Record<string, string | undefined>;
|
|
|
|
@Prop({ type: String, required: false })
|
|
visitLocation?: string;
|
|
|
|
@Prop({ type: Number, required: false })
|
|
claimNo?: number;
|
|
|
|
@Prop({ type: Number, required: false })
|
|
claimId?: number;
|
|
}
|
|
|
|
export const ClaimRequestManagementSchema = SchemaFactory.createForClass(
|
|
ClaimRequestManagementModel,
|
|
);
|