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; } 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; } 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; } 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; /** Damage expert profile when in-person visit was requested (V1). */ @Prop({ type: Object }) damageExpertInPersonVisitProfileSnapshot?: Record; @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, );