forked from Yara724/api
Initial commit after migration to gitea
This commit is contained in:
@@ -0,0 +1,483 @@
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { extname, parse } from "node:path";
|
||||
import {
|
||||
BadRequestException,
|
||||
Body,
|
||||
Controller,
|
||||
Get,
|
||||
Param,
|
||||
Patch,
|
||||
Post,
|
||||
Put,
|
||||
Query,
|
||||
UploadedFile,
|
||||
UseGuards,
|
||||
UseInterceptors,
|
||||
} from "@nestjs/common";
|
||||
import { FileInterceptor } from "@nestjs/platform-express";
|
||||
import {
|
||||
ApiBearerAuth,
|
||||
ApiBody,
|
||||
ApiConsumes,
|
||||
ApiParam,
|
||||
ApiQuery,
|
||||
ApiTags,
|
||||
} from "@nestjs/swagger";
|
||||
import { diskStorage } from "multer";
|
||||
import { GlobalGuard } from "src/auth/guards/global.guard";
|
||||
import { ClaimAccessGuard } from "src/auth/guards/claim-access.guard";
|
||||
import { RolesGuard } from "src/auth/guards/role.guard";
|
||||
import { Roles } from "src/decorators/roles.decorator";
|
||||
import { CurrentUser } from "src/decorators/user.decorator";
|
||||
import { RoleEnum } from "src/Types&Enums/role.enum";
|
||||
import { ClaimRequestManagementService } from "./claim-request-management.service";
|
||||
import { CarDamagePartDto, OtherCarDamagePartDto } from "./dto/car-part.dto";
|
||||
import { UserCommentDto } from "./dto/user-comment.dto";
|
||||
import { UserObjectionDto } from "./dto/user-objection.dto";
|
||||
import { InPersonVisitDto } from "./dto/in-person-visit.dto";
|
||||
|
||||
@Controller("claim-request-management")
|
||||
@ApiTags("claim-request-management")
|
||||
@Roles(RoleEnum.USER, RoleEnum.EXPERT, RoleEnum.DAMAGE_EXPERT)
|
||||
@UseGuards(ClaimAccessGuard, RolesGuard)
|
||||
@ApiBearerAuth()
|
||||
export class ClaimRequestManagementController {
|
||||
constructor(
|
||||
private readonly claimRequestManagementService: ClaimRequestManagementService,
|
||||
) {}
|
||||
|
||||
@ApiParam({ name: "blameId" })
|
||||
@Post("/:blameId")
|
||||
async createClaimRequest(
|
||||
@Param("blameId") requestId: string,
|
||||
@CurrentUser() user,
|
||||
) {
|
||||
return await this.claimRequestManagementService.createClaimRequest(
|
||||
requestId,
|
||||
user.role === RoleEnum.USER ? user.sub : undefined,
|
||||
user,
|
||||
);
|
||||
}
|
||||
|
||||
@ApiBody({ type: CarDamagePartDto })
|
||||
@Patch("/car-part-damage/:claimRequestID")
|
||||
@ApiParam({ name: "claimRequestID" })
|
||||
async carPartDamage(
|
||||
@Param("claimRequestID") requestId: string,
|
||||
@Body() body: CarDamagePartDto,
|
||||
@CurrentUser() user,
|
||||
) {
|
||||
return await this.claimRequestManagementService.selectCarPartDamage(
|
||||
requestId,
|
||||
body,
|
||||
user,
|
||||
);
|
||||
}
|
||||
|
||||
@Get("/car-other-part")
|
||||
async getCarOtherParts() {
|
||||
const carOtherPart = await readFile(
|
||||
`${process.cwd()}/src/static/car-part.json`,
|
||||
"utf-8",
|
||||
);
|
||||
return carOtherPart;
|
||||
}
|
||||
|
||||
@ApiBody({ type: OtherCarDamagePartDto })
|
||||
@ApiParam({ name: "claimRequestID" })
|
||||
@UseInterceptors(
|
||||
FileInterceptor("file", {
|
||||
limits: {
|
||||
fileSize: 10 * 1024 * 1024,
|
||||
},
|
||||
storage: diskStorage({
|
||||
destination: "./files/car-green-cards",
|
||||
filename: (req, file, callback) => {
|
||||
const unique = Date.now();
|
||||
const ex = extname(file.originalname);
|
||||
const filename = `${file.originalname.split(" ")[0]}-${unique}${ex}`;
|
||||
callback(null, filename);
|
||||
},
|
||||
}),
|
||||
}),
|
||||
)
|
||||
@ApiConsumes("multipart/form-data")
|
||||
@Patch("/car-other-part-damage/:claimRequestID")
|
||||
async carOtherPartDamage(
|
||||
@Param("claimRequestID") requestId: string,
|
||||
@UploadedFile() file,
|
||||
@Body() body: OtherCarDamagePartDto,
|
||||
@CurrentUser() user,
|
||||
) {
|
||||
return await this.claimRequestManagementService.selectCarOtherPartDamage(
|
||||
requestId,
|
||||
body,
|
||||
file,
|
||||
user,
|
||||
);
|
||||
}
|
||||
|
||||
@Get("required-documents-status/:claimRequestID")
|
||||
@ApiParam({ name: "claimRequestID" })
|
||||
async getRequiredDocumentsStatus(
|
||||
@Param("claimRequestID") requestId: string,
|
||||
) {
|
||||
return await this.claimRequestManagementService.getRequiredDocumentsStatus(
|
||||
requestId,
|
||||
);
|
||||
}
|
||||
|
||||
@Get("car-part-image-required/:claimRequestID")
|
||||
@ApiParam({ name: "claimRequestID" })
|
||||
async getImageRequired(@Param("claimRequestID") requestId) {
|
||||
return await this.claimRequestManagementService.getImageRequiredList(
|
||||
requestId,
|
||||
);
|
||||
}
|
||||
|
||||
@ApiBody({
|
||||
schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
file: { type: "string", format: "binary" },
|
||||
},
|
||||
},
|
||||
})
|
||||
@UseInterceptors(
|
||||
FileInterceptor("file", {
|
||||
limits: { fileSize: 10 * 1024 * 1024 },
|
||||
storage: diskStorage({
|
||||
destination: "./files/claim-required-documents/",
|
||||
filename: (req, file, callback) => {
|
||||
const extension = extname(file.originalname);
|
||||
const basename = parse(file.originalname).name;
|
||||
const unique = Date.now();
|
||||
const sanitizedBasename = basename
|
||||
.replace(/\s/g, "_")
|
||||
.replace(/[^\w\-_]/g, "")
|
||||
.substring(0, 50);
|
||||
const filename = `${sanitizedBasename}-${unique}${extension}`;
|
||||
callback(null, filename);
|
||||
},
|
||||
}),
|
||||
}),
|
||||
)
|
||||
@ApiConsumes("multipart/form-data")
|
||||
@ApiParam({ name: "claimRequestID" })
|
||||
@ApiQuery({
|
||||
name: "documentType",
|
||||
enum: [
|
||||
"damaged_driving_license_back",
|
||||
"damaged_driving_license_front",
|
||||
"damaged_chassis_number",
|
||||
"damaged_engine_photo",
|
||||
"damaged_car_card_front",
|
||||
"damaged_car_card_back",
|
||||
"damaged_metal_plate",
|
||||
"guilty_driving_license_front",
|
||||
"guilty_driving_license_back",
|
||||
"guilty_car_card_front",
|
||||
"guilty_car_card_back",
|
||||
"guilty_metal_plate",
|
||||
],
|
||||
description: "Type of required document to upload",
|
||||
})
|
||||
@Patch("upload-required-document/:claimRequestID")
|
||||
async uploadRequiredDocument(
|
||||
@Param("claimRequestID") requestId: string,
|
||||
@Query("documentType") documentType: string,
|
||||
@UploadedFile("file") file: Express.Multer.File,
|
||||
@CurrentUser() user,
|
||||
) {
|
||||
if (!file) {
|
||||
throw new BadRequestException("File is required");
|
||||
}
|
||||
return await this.claimRequestManagementService.uploadRequiredDocument(
|
||||
requestId,
|
||||
documentType as any,
|
||||
file,
|
||||
user,
|
||||
);
|
||||
}
|
||||
|
||||
@ApiBody({
|
||||
schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
file: { type: "string", format: "binary" },
|
||||
},
|
||||
},
|
||||
})
|
||||
@UseInterceptors(
|
||||
FileInterceptor("file", {
|
||||
limits: { fileSize: 10 * 1024 * 1024 },
|
||||
storage: diskStorage({
|
||||
destination: "./files/car-parts/",
|
||||
filename: (req, file, callback) => {
|
||||
const extension = extname(file.originalname);
|
||||
const basename = parse(file.originalname).name;
|
||||
const unique = Date.now();
|
||||
// Sanitize filename: remove non-ASCII characters and special chars to avoid encoding issues
|
||||
const sanitizedBasename = basename
|
||||
.replace(/\s/g, "_")
|
||||
.replace(/[^\w\-_]/g, "") // Remove all non-word characters except hyphens and underscores
|
||||
.substring(0, 50); // Limit length
|
||||
const filename = `${sanitizedBasename}-${unique}${extension}`;
|
||||
callback(null, filename);
|
||||
},
|
||||
}),
|
||||
}),
|
||||
)
|
||||
@ApiConsumes("multipart/form-data")
|
||||
@ApiParam({ name: "claimRequestID" })
|
||||
@ApiParam({
|
||||
name: "partId",
|
||||
description: "The ID of the specific car part being photographed.",
|
||||
})
|
||||
@Patch("capture-car-part-damage/:claimRequestID/:partId")
|
||||
async captureCarPartDamage(
|
||||
@Param("partId") partId: string,
|
||||
@Param("claimRequestID") requestId: string,
|
||||
@UploadedFile("file") file: Express.Multer.File,
|
||||
) {
|
||||
if (!file) {
|
||||
throw new BadRequestException("Image file is required.");
|
||||
}
|
||||
return await this.claimRequestManagementService.setDamageImage(
|
||||
requestId,
|
||||
partId,
|
||||
file,
|
||||
);
|
||||
}
|
||||
|
||||
@ApiBody({
|
||||
schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
file: { type: "string", format: "binary" },
|
||||
},
|
||||
},
|
||||
})
|
||||
@UseInterceptors(
|
||||
FileInterceptor("file", {
|
||||
limits: { fileSize: 50 * 1024 * 1024 },
|
||||
storage: diskStorage({
|
||||
destination: "./files/car-capture-videos/",
|
||||
filename: (req, file, callback) => {
|
||||
const unique = Date.now();
|
||||
const ex = extname(file.originalname);
|
||||
const filename = `claim-video-${unique}${ex}`;
|
||||
callback(null, filename);
|
||||
},
|
||||
}),
|
||||
}),
|
||||
)
|
||||
@ApiConsumes("multipart/form-data")
|
||||
@ApiParam({ name: "claimRequestID" })
|
||||
@Patch("car-capture/:claimRequestID")
|
||||
async captureVideoCapture(
|
||||
@Param("claimRequestID") requestId: string,
|
||||
@UploadedFile("file") file: Express.Multer.File,
|
||||
) {
|
||||
return await this.claimRequestManagementService.setVideoCapture(
|
||||
requestId,
|
||||
file,
|
||||
);
|
||||
}
|
||||
|
||||
@Get("requests/")
|
||||
async getRequest(@CurrentUser() currentUser) {
|
||||
return await this.claimRequestManagementService.myRequests(currentUser);
|
||||
}
|
||||
|
||||
@Get("request/:claimRequestId")
|
||||
@ApiParam({ name: "claimRequestId" })
|
||||
myRequests(
|
||||
@Param("claimRequestId") requestId: string,
|
||||
@CurrentUser() user,
|
||||
) {
|
||||
return this.claimRequestManagementService.requestDetails(requestId, user);
|
||||
}
|
||||
|
||||
@Put("request/reply/:claimRequestId")
|
||||
@ApiParam({ name: "claimRequestId" })
|
||||
@UseInterceptors(
|
||||
FileInterceptor("file", {
|
||||
limits: {
|
||||
fileSize: 10 * 1024 * 1024,
|
||||
},
|
||||
storage: diskStorage({
|
||||
destination: "./files/claim-sign",
|
||||
filename: (req, file, callback) => {
|
||||
const unique = Date.now();
|
||||
const ex = extname(file.originalname);
|
||||
const filename = `${file.originalname.split(" ")[0]}-${unique}${ex}`;
|
||||
callback(null, filename);
|
||||
},
|
||||
}),
|
||||
}),
|
||||
)
|
||||
@ApiBody({
|
||||
type: UserCommentDto,
|
||||
description: "if partId null , you can upload video capture",
|
||||
})
|
||||
@ApiConsumes("multipart/form-data")
|
||||
@ApiParam({ name: "claimRequestId" })
|
||||
async submitReply(
|
||||
@Param("claimRequestId") requestId,
|
||||
@Body() body,
|
||||
@UploadedFile() file: Express.Multer.File,
|
||||
@CurrentUser() user,
|
||||
) {
|
||||
return await this.claimRequestManagementService.submitUserReply(
|
||||
requestId,
|
||||
body,
|
||||
file,
|
||||
user,
|
||||
);
|
||||
}
|
||||
|
||||
@Put("request/resend/:claimRequestId/objection")
|
||||
@ApiParam({ name: "claimRequestId" })
|
||||
@ApiConsumes("application/json")
|
||||
@ApiBody({
|
||||
type: UserObjectionDto,
|
||||
description: "Objection details with optional new parts",
|
||||
})
|
||||
async handleUserObjection(
|
||||
@Param("claimRequestId") claimRequestId: string,
|
||||
@Body() userObjectionDto: UserObjectionDto,
|
||||
) {
|
||||
return await this.claimRequestManagementService.handleUserObjectionAndParts(
|
||||
claimRequestId,
|
||||
userObjectionDto,
|
||||
);
|
||||
}
|
||||
|
||||
@Patch("request/resend/:claimRequestId")
|
||||
@ApiConsumes("multipart/form-data")
|
||||
@ApiParam({ name: "claimRequestId" })
|
||||
@ApiQuery({ name: "fields", enum: ["resendDocuments", "resendCarParts"] })
|
||||
@ApiQuery({ name: "partId", required: false })
|
||||
@ApiQuery({ name: "documentName", required: false })
|
||||
@ApiQuery({ name: "side", required: false })
|
||||
@ApiBody({
|
||||
schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
file: {
|
||||
type: "string",
|
||||
format: "binary",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
@UseInterceptors(
|
||||
FileInterceptor("file", {
|
||||
storage: diskStorage({
|
||||
destination: "./files/claim-resend-documents",
|
||||
filename: (req, file, callback) => {
|
||||
const unique = Date.now();
|
||||
const ext = extname(file.originalname);
|
||||
const filename = `${file.originalname.split(" ")[0]}-${unique}${ext}`;
|
||||
callback(null, filename);
|
||||
},
|
||||
}),
|
||||
limits: { fileSize: 10 * 1024 * 1024 },
|
||||
}),
|
||||
)
|
||||
async uploadDocuments(
|
||||
@Param("claimRequestId") claimId: string,
|
||||
@Query() query: string,
|
||||
@UploadedFile() file: Express.Multer.File,
|
||||
@CurrentUser() user,
|
||||
) {
|
||||
return await this.claimRequestManagementService.resendFiles(
|
||||
claimId,
|
||||
file,
|
||||
query,
|
||||
user,
|
||||
);
|
||||
}
|
||||
|
||||
@Patch("request/reply/:claimRequestId/:partId/upload-factor")
|
||||
@ApiConsumes("multipart/form-data")
|
||||
@ApiParam({ name: "claimRequestId" })
|
||||
@ApiParam({ name: "partId" })
|
||||
@ApiBody({
|
||||
schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
file: {
|
||||
type: "string",
|
||||
format: "binary",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
@UseInterceptors(
|
||||
FileInterceptor("file", {
|
||||
storage: diskStorage({
|
||||
destination: "./files/claim-factors",
|
||||
filename: (req, file, callback) => {
|
||||
const unique = Date.now();
|
||||
const filename = `-${unique}-${file.originalname}`;
|
||||
callback(null, filename);
|
||||
},
|
||||
}),
|
||||
limits: { fileSize: 10 * 1024 * 1024 },
|
||||
}),
|
||||
)
|
||||
async uploadFactorForPart(
|
||||
@Param("claimRequestId") claimId: string,
|
||||
@Param("partId") partId: string,
|
||||
@UploadedFile() file: Express.Multer.File,
|
||||
@CurrentUser() user,
|
||||
) {
|
||||
return await this.claimRequestManagementService.uploadClaimFactor(
|
||||
claimId,
|
||||
partId,
|
||||
file,
|
||||
user,
|
||||
);
|
||||
}
|
||||
|
||||
@ApiBody({ type: InPersonVisitDto })
|
||||
@ApiParam({ name: "id" })
|
||||
@Patch(":id/visit")
|
||||
async inPersonVisit(
|
||||
@Param("id") requestId: string,
|
||||
@Body() body: InPersonVisitDto,
|
||||
@CurrentUser() actor,
|
||||
) {
|
||||
// Pass the branchId from the body to the service
|
||||
return await this.claimRequestManagementService.inPersonVisit(
|
||||
requestId,
|
||||
body.branchId,
|
||||
actor,
|
||||
);
|
||||
}
|
||||
|
||||
@Get("branches/:insuranceId")
|
||||
async insuranceBranches(@Param("insuranceId") insuranceId: string) {
|
||||
return await this.claimRequestManagementService.retrieveInsuranceBranches(
|
||||
insuranceId,
|
||||
);
|
||||
}
|
||||
|
||||
@Get("fanavaran-submit/:claimRequestId")
|
||||
@ApiParam({ name: "claimRequestId" })
|
||||
async fanavaranSubmit(@Param("claimRequestId") claimRequestId: string) {
|
||||
return await this.claimRequestManagementService.fanavaranSubmit(
|
||||
claimRequestId,
|
||||
);
|
||||
}
|
||||
|
||||
@Post("fanavaran-submit/:claimRequestId")
|
||||
@ApiParam({ name: "claimRequestId" })
|
||||
async submitToFanavaran(@Param("claimRequestId") claimRequestId: string) {
|
||||
return await this.claimRequestManagementService.submitToFanavaran(
|
||||
claimRequestId,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
import { MongooseModule } from "@nestjs/mongoose";
|
||||
import { AiModule } from "src/ai/ai.module";
|
||||
import { SandHubModule } from "src/sand-hub/sand-hub.module";
|
||||
import { RequestManagementModule } from "src/request-management/request-management.module";
|
||||
import { UsersModule } from "src/users/users.module";
|
||||
import { ClaimRequestManagementController } from "./claim-request-management.controller";
|
||||
import { ClaimRequestManagementService } from "./claim-request-management.service";
|
||||
import { CarGreenCardDbService } from "./entites/db-service/car-green-card.db.service";
|
||||
import { ClaimRequestManagementDbService } from "./entites/db-service/claim-request-management.db.service";
|
||||
import { ClaimSignDbService } from "./entites/db-service/claim-sign.db.service";
|
||||
import { DamageImageDbService } from "./entites/db-service/damage-image.db.service";
|
||||
import { ClaimFactorsImageDbService } from "./entites/db-service/factor-image.db.service";
|
||||
import { VideoCaptureDbService } from "./entites/db-service/video-capture.db.service";
|
||||
import { ClaimRequiredDocumentDbService } from "./entites/db-service/claim-required-document.db.service";
|
||||
import {
|
||||
CarGreenCardModel,
|
||||
CarGreenCardSchema,
|
||||
} from "./entites/schema/car-green-card.schema";
|
||||
import {
|
||||
ClaimRequiredDocument,
|
||||
ClaimRequiredDocumentSchema,
|
||||
} from "./entites/schema/claim-required-document.schema";
|
||||
import {
|
||||
ClaimRequestManagementModel,
|
||||
ClaimRequestManagementSchema,
|
||||
} from "./entites/schema/claim-request-management.schema";
|
||||
import { ClaimSignModel, ClaimSignSchema } from "./entites/schema/claim-sign";
|
||||
import {
|
||||
DamageImageModelSchema,
|
||||
DamagePartImageModel,
|
||||
} from "./entites/schema/damage-image-part.schema";
|
||||
import {
|
||||
ClaimFactorsImage,
|
||||
ClaimFactorsImageSchema,
|
||||
} from "./entites/schema/factor-image.schema";
|
||||
import {
|
||||
VideoCaptureModel,
|
||||
VideoCaptureSchema,
|
||||
} from "./entites/schema/video-capture.schema";
|
||||
import { ClientModule } from "src/client/client.module";
|
||||
import { ClaimAccessGuard } from "src/auth/guards/claim-access.guard";
|
||||
import { JwtModule } from "@nestjs/jwt";
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
UsersModule,
|
||||
RequestManagementModule,
|
||||
AiModule,
|
||||
SandHubModule,
|
||||
ClientModule,
|
||||
JwtModule.register({}),
|
||||
MongooseModule.forFeature([
|
||||
{
|
||||
name: ClaimRequestManagementModel.name,
|
||||
schema: ClaimRequestManagementSchema,
|
||||
},
|
||||
{ name: CarGreenCardModel.name, schema: CarGreenCardSchema },
|
||||
{ name: DamagePartImageModel.name, schema: DamageImageModelSchema },
|
||||
{ name: ClaimSignModel.name, schema: ClaimSignSchema },
|
||||
{ name: ClaimFactorsImage.name, schema: ClaimFactorsImageSchema },
|
||||
{ name: VideoCaptureModel.name, schema: VideoCaptureSchema },
|
||||
{
|
||||
name: ClaimRequiredDocument.name,
|
||||
schema: ClaimRequiredDocumentSchema,
|
||||
},
|
||||
]),
|
||||
],
|
||||
providers: [
|
||||
ClaimRequestManagementService,
|
||||
ClaimRequestManagementDbService,
|
||||
CarGreenCardDbService,
|
||||
DamageImageDbService,
|
||||
ClaimSignDbService,
|
||||
ClaimFactorsImageDbService,
|
||||
VideoCaptureDbService,
|
||||
ClaimRequiredDocumentDbService,
|
||||
ClaimAccessGuard,
|
||||
],
|
||||
controllers: [ClaimRequestManagementController],
|
||||
exports: [
|
||||
ClaimRequestManagementDbService,
|
||||
DamageImageDbService,
|
||||
VideoCaptureDbService,
|
||||
ClaimRequiredDocumentDbService,
|
||||
],
|
||||
})
|
||||
export class ClaimRequestManagementModule {}
|
||||
2556
src/claim-request-management/claim-request-management.service.ts
Normal file
2556
src/claim-request-management/claim-request-management.service.ts
Normal file
File diff suppressed because it is too large
Load Diff
108
src/claim-request-management/dto/car-part.dto.ts
Normal file
108
src/claim-request-management/dto/car-part.dto.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
import { ApiProperty } from "@nestjs/swagger";
|
||||
|
||||
export class MainParts {
|
||||
@ApiProperty({ default: false })
|
||||
backFender: boolean;
|
||||
|
||||
@ApiProperty({ default: false })
|
||||
backWheel: boolean;
|
||||
|
||||
@ApiProperty({ default: false })
|
||||
backDoor: boolean;
|
||||
|
||||
@ApiProperty({ default: false })
|
||||
frontDoor: boolean;
|
||||
|
||||
@ApiProperty({ default: false })
|
||||
mirror: boolean;
|
||||
|
||||
@ApiProperty({ default: false })
|
||||
frontWheel: boolean;
|
||||
|
||||
@ApiProperty({ default: false })
|
||||
frontFender: boolean;
|
||||
|
||||
@ApiProperty({ default: false })
|
||||
backWindow: boolean;
|
||||
|
||||
@ApiProperty({ default: false })
|
||||
frontWindow: boolean;
|
||||
}
|
||||
export class FrontParts {
|
||||
@ApiProperty({ default: false })
|
||||
frontBumper: boolean;
|
||||
|
||||
@ApiProperty({ default: false })
|
||||
frontCarWindshield: boolean;
|
||||
|
||||
@ApiProperty({ default: false })
|
||||
carHood: boolean;
|
||||
|
||||
@ApiProperty({ default: false })
|
||||
leftLight: boolean;
|
||||
|
||||
@ApiProperty({ default: false })
|
||||
rightLight: boolean;
|
||||
|
||||
@ApiProperty({ default: false, description: "جلو پنجره " })
|
||||
frontGrille: boolean;
|
||||
}
|
||||
export class BackParts {
|
||||
@ApiProperty({ default: false })
|
||||
backBumper: boolean;
|
||||
|
||||
@ApiProperty({ default: false })
|
||||
carTrunk: boolean;
|
||||
|
||||
@ApiProperty({ default: false })
|
||||
backCarWindshield: boolean;
|
||||
|
||||
@ApiProperty({ default: false })
|
||||
leftLight: boolean;
|
||||
|
||||
@ApiProperty({ default: false })
|
||||
rightLight: boolean;
|
||||
}
|
||||
export class TopParts {
|
||||
@ApiProperty({ default: false })
|
||||
roof: boolean;
|
||||
}
|
||||
export class CarDamagePartDto {
|
||||
@ApiProperty({ type: MainParts })
|
||||
left: MainParts[];
|
||||
|
||||
@ApiProperty({ type: MainParts })
|
||||
right: MainParts[];
|
||||
|
||||
@ApiProperty({ type: FrontParts })
|
||||
front: FrontParts[];
|
||||
|
||||
@ApiProperty({ type: BackParts })
|
||||
back: BackParts[];
|
||||
|
||||
@ApiProperty({ type: TopParts })
|
||||
top: TopParts[];
|
||||
}
|
||||
|
||||
export class OtherCarDamagePartDto {
|
||||
@ApiProperty({
|
||||
format: "array",
|
||||
description: "please add items of json into array",
|
||||
example: [{ "حسگر درها": true }],
|
||||
})
|
||||
otherParts: [];
|
||||
|
||||
@ApiProperty({ format: "string" })
|
||||
sheba: string;
|
||||
|
||||
@ApiProperty({ format: "string" })
|
||||
nationalCodeOfInsurer: string;
|
||||
|
||||
@ApiProperty({ type: "string", format: "binary", required: true })
|
||||
file: Express.Multer.File;
|
||||
}
|
||||
|
||||
export class CaptureCarPartDto {
|
||||
@ApiProperty({ type: "string", format: "binary", required: true })
|
||||
file: Express.Multer.File;
|
||||
}
|
||||
16
src/claim-request-management/dto/claim-detail.ts
Normal file
16
src/claim-request-management/dto/claim-detail.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { ClaimRequestManagementModel } from "src/claim-request-management/entites/schema/claim-request-management.schema";
|
||||
|
||||
export class ClaimPartUploadDetail {
|
||||
list: any;
|
||||
constructor(claimFile: ClaimRequestManagementModel[]) {
|
||||
this.list = claimFile
|
||||
.map((c) => {
|
||||
return {
|
||||
carPartDamage: c.carPartDamage,
|
||||
carOtherPartDamage: c.otherParts,
|
||||
greenCardUpload: !!c.carGreenCard.path,
|
||||
};
|
||||
})
|
||||
.flat(2);
|
||||
}
|
||||
}
|
||||
17
src/claim-request-management/dto/claim-rs-dto.ts
Normal file
17
src/claim-request-management/dto/claim-rs-dto.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { ClaimRequestManagementModel } from "src/claim-request-management/entites/schema/claim-request-management.schema";
|
||||
import { ReqClaimStatus } from "src/Types&Enums/claim-request-management/status.enum";
|
||||
|
||||
export class ClaimRequestDtoRs {
|
||||
requestDetail: any;
|
||||
messsage: string;
|
||||
status: ReqClaimStatus;
|
||||
constructor(
|
||||
req: ClaimRequestManagementModel,
|
||||
message: string,
|
||||
status: ReqClaimStatus,
|
||||
) {
|
||||
this.requestDetail = req;
|
||||
this.messsage = message;
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
8
src/claim-request-management/dto/create-claim.dto.ts
Normal file
8
src/claim-request-management/dto/create-claim.dto.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export class CreateClaimRequestDtoRs {
|
||||
message: string;
|
||||
requestId: string;
|
||||
constructor(requestId: string, message: string) {
|
||||
this.requestId = requestId;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
8
src/claim-request-management/dto/image-required.dto.ts
Normal file
8
src/claim-request-management/dto/image-required.dto.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { ClaimRequestManagementModel } from "src/claim-request-management/entites/schema/claim-request-management.schema";
|
||||
|
||||
export class ImageRequiredDto {
|
||||
public list: {} = {};
|
||||
constructor(imageModel: ClaimRequestManagementModel) {
|
||||
this.list = imageModel.imageRequired;
|
||||
}
|
||||
}
|
||||
12
src/claim-request-management/dto/in-person-visit.dto.ts
Normal file
12
src/claim-request-management/dto/in-person-visit.dto.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { IsMongoId, IsNotEmpty } from "class-validator";
|
||||
|
||||
export class InPersonVisitDto {
|
||||
@ApiProperty({
|
||||
example: "60d5ec49e7b2f8001c8e4d2a",
|
||||
description: "The unique ID of the branch the user is being sent to.",
|
||||
})
|
||||
@IsNotEmpty()
|
||||
@IsMongoId()
|
||||
branchId: string;
|
||||
}
|
||||
23
src/claim-request-management/dto/my-request.dto.ts
Normal file
23
src/claim-request-management/dto/my-request.dto.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { Types } from "mongoose";
|
||||
import { ClaimRequestManagementModel } from "src/claim-request-management/entites/schema/claim-request-management.schema";
|
||||
import { ReqClaimStatus } from "src/Types&Enums/claim-request-management/status.enum";
|
||||
|
||||
export class MyRequestsDtoList {
|
||||
status: ReqClaimStatus;
|
||||
submitDate: string;
|
||||
numberOfRequest: number;
|
||||
_id: Types.ObjectId;
|
||||
constructor(request: ClaimRequestManagementModel) {
|
||||
this._id = request["_id"];
|
||||
this.status = request.claimStatus;
|
||||
this.submitDate = new Date(request.createdAt).toLocaleString("fa-IR");
|
||||
this.numberOfRequest = request.requestNumber;
|
||||
}
|
||||
}
|
||||
|
||||
export class MyRequestsDto {
|
||||
public list = [];
|
||||
constructor(requests: ClaimRequestManagementModel[]) {
|
||||
this.list = requests.map((r) => new MyRequestsDtoList(r));
|
||||
}
|
||||
}
|
||||
19
src/claim-request-management/dto/submit-reply.dto.ts
Normal file
19
src/claim-request-management/dto/submit-reply.dto.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { ClaimRequestManagementModel } from "src/claim-request-management/entites/schema/claim-request-management.schema";
|
||||
import { UserCommentDto } from "src/claim-request-management/dto/user-comment.dto";
|
||||
|
||||
export class SubmitUserReplyDtoRs {
|
||||
requestId: string;
|
||||
partsNeedFactorDetail: object;
|
||||
partsNeedFactor: boolean;
|
||||
userComment: UserCommentDto;
|
||||
constructor(
|
||||
claim: ClaimRequestManagementModel,
|
||||
partsFactorDetail?,
|
||||
partsNeedFactor?,
|
||||
) {
|
||||
this.requestId = claim["_id"];
|
||||
this.partsNeedFactorDetail = partsFactorDetail;
|
||||
this.partsNeedFactor = partsNeedFactor;
|
||||
this.userComment = claim.damageExpertReply.userComment;
|
||||
}
|
||||
}
|
||||
12
src/claim-request-management/dto/user-comment.dto.ts
Normal file
12
src/claim-request-management/dto/user-comment.dto.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { ApiProperty } from "@nestjs/swagger";
|
||||
|
||||
export class UserCommentDto {
|
||||
@ApiProperty({ type: Boolean })
|
||||
isAccept: boolean;
|
||||
|
||||
@ApiProperty({ type: "string", format: "binary", required: false })
|
||||
file?: Express.Multer.File;
|
||||
|
||||
@ApiProperty({ type: String })
|
||||
branch?: string;
|
||||
}
|
||||
47
src/claim-request-management/dto/user-objection.dto.ts
Normal file
47
src/claim-request-management/dto/user-objection.dto.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { Type } from "class-transformer";
|
||||
import { TypeOfDamage } from "src/Types&Enums/claim-request-management/type-of-damage.enum";
|
||||
|
||||
export class UserObjectionPartDto {
|
||||
@ApiProperty()
|
||||
partId: string;
|
||||
|
||||
@ApiProperty({ required: false })
|
||||
reason?: string;
|
||||
|
||||
@ApiProperty({ required: false })
|
||||
partPrice?: string;
|
||||
|
||||
@ApiProperty({ required: false })
|
||||
partSalary?: string;
|
||||
|
||||
@ApiProperty({ required: false })
|
||||
typeOfDamage?: TypeOfDamage;
|
||||
|
||||
@ApiProperty({ required: false })
|
||||
carPartDamage?: string;
|
||||
|
||||
@ApiProperty({ required: false })
|
||||
side?: string;
|
||||
}
|
||||
|
||||
export class NewPartDto {
|
||||
@ApiProperty({ required: false, nullable: true })
|
||||
partId: string | null;
|
||||
|
||||
@ApiProperty()
|
||||
partName: string;
|
||||
|
||||
@ApiProperty({ required: false })
|
||||
side?: string;
|
||||
}
|
||||
|
||||
export class UserObjectionDto {
|
||||
@ApiProperty({ type: [UserObjectionPartDto], required: false })
|
||||
@Type(() => UserObjectionPartDto)
|
||||
objectionParts?: UserObjectionPartDto[];
|
||||
|
||||
@ApiProperty({ type: [NewPartDto], required: false })
|
||||
@Type(() => NewPartDto)
|
||||
newParts?: NewPartDto[];
|
||||
}
|
||||
4
src/claim-request-management/dto/user-reply.dto.ts
Normal file
4
src/claim-request-management/dto/user-reply.dto.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export class UserReplyDtoRs {
|
||||
requestId: string;
|
||||
isAccept: string;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { InjectModel } from "@nestjs/mongoose";
|
||||
import { FilterQuery, Model } from "mongoose";
|
||||
import { CarGreenCardModel } from "src/claim-request-management/entites/schema/car-green-card.schema";
|
||||
|
||||
export class CarGreenCardDbService {
|
||||
constructor(
|
||||
@InjectModel(CarGreenCardModel.name)
|
||||
private readonly model: Model<CarGreenCardModel>,
|
||||
) {}
|
||||
async create(greenCard): Promise<CarGreenCardModel> {
|
||||
return await this.model.create(greenCard);
|
||||
}
|
||||
|
||||
async findOne(
|
||||
filter: FilterQuery<CarGreenCardModel>,
|
||||
): Promise<CarGreenCardModel> {
|
||||
return await this.model.findOne({ filter });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { InjectModel } from "@nestjs/mongoose";
|
||||
import { FilterQuery, Model, Types, UpdateQuery } from "mongoose";
|
||||
import { ClaimRequestManagementModel } from "src/claim-request-management/entites/schema/claim-request-management.schema";
|
||||
const crypto = require("node:crypto");
|
||||
|
||||
@Injectable()
|
||||
export class ClaimRequestManagementDbService {
|
||||
constructor(
|
||||
@InjectModel(ClaimRequestManagementModel.name)
|
||||
private readonly model: Model<ClaimRequestManagementModel>,
|
||||
) {}
|
||||
|
||||
async create(
|
||||
claimRequest: ClaimRequestManagementModel,
|
||||
): Promise<ClaimRequestManagementModel> {
|
||||
const uniqueRequestNumber = await this.generateUniqueNumbers();
|
||||
return this.model.create({
|
||||
...claimRequest,
|
||||
requestNumber: uniqueRequestNumber,
|
||||
});
|
||||
}
|
||||
|
||||
async findOne(
|
||||
id?: string,
|
||||
filter?: FilterQuery<ClaimRequestManagementModel>,
|
||||
) {
|
||||
if (filter) return await this.model.findOne(filter);
|
||||
return await this.model.findOne({ _id: new Types.ObjectId(id) });
|
||||
}
|
||||
|
||||
async findOneDocument(
|
||||
id: string,
|
||||
filter?: FilterQuery<ClaimRequestManagementModel>,
|
||||
) {
|
||||
if (filter) return await this.model.findOne(filter);
|
||||
return await this.model.findOne({ _id: new Types.ObjectId(id) }).lean();
|
||||
}
|
||||
|
||||
async findOneAndUpdate(
|
||||
filter: FilterQuery<ClaimRequestManagementModel>,
|
||||
update: UpdateQuery<ClaimRequestManagementModel>,
|
||||
option?,
|
||||
) {
|
||||
return await this.model.findOneAndUpdate(filter, update, option);
|
||||
}
|
||||
|
||||
async findAllByStatus(filter: FilterQuery<ClaimRequestManagementModel>) {
|
||||
return await this.model.find(filter);
|
||||
}
|
||||
|
||||
async findAndDelete(
|
||||
filter: FilterQuery<ClaimRequestManagementModel>,
|
||||
option,
|
||||
) {
|
||||
return await this.model.deleteMany(filter, option);
|
||||
}
|
||||
|
||||
async findAllAndPagination(
|
||||
filter: FilterQuery<ClaimRequestManagementModel>,
|
||||
currentPage: number,
|
||||
countPerPage: number,
|
||||
) {
|
||||
const responsePerPage = countPerPage | 1;
|
||||
const skipPge = responsePerPage * (Number(currentPage) - 1);
|
||||
return await this.model.find(filter).limit(responsePerPage).skip(skipPge);
|
||||
}
|
||||
|
||||
async aggregate(filter?) {
|
||||
return await this.model.aggregate(filter);
|
||||
}
|
||||
|
||||
async findAndUpdate(
|
||||
id: string,
|
||||
update: UpdateQuery<ClaimRequestManagementModel>,
|
||||
option?: FilterQuery<ClaimRequestManagementModel>,
|
||||
) {
|
||||
return await this.model.findByIdAndUpdate(
|
||||
{ _id: new Types.ObjectId(id) },
|
||||
update,
|
||||
option,
|
||||
);
|
||||
}
|
||||
|
||||
async findAllByAnyFilter(
|
||||
filter: FilterQuery<ClaimRequestManagementModel>,
|
||||
): Promise<ClaimRequestManagementModel[]> {
|
||||
return await this.model.find(filter);
|
||||
}
|
||||
|
||||
async countByFilter(
|
||||
filter: FilterQuery<ClaimRequestManagementModel>,
|
||||
): Promise<number> {
|
||||
return await this.model.countDocuments(filter);
|
||||
}
|
||||
async findAll(): Promise<ClaimRequestManagementModel[]> {
|
||||
return await this.model.find();
|
||||
}
|
||||
async generateUniqueNumbers(digits = 5) {
|
||||
try {
|
||||
const max = Math.pow(10, digits);
|
||||
const randomBytes = crypto.randomBytes(Math.ceil(digits / 2));
|
||||
const randomNumber = parseInt(randomBytes.toString("hex"), 16) % max;
|
||||
return randomNumber.toString().padStart(digits, "0");
|
||||
} catch (error) {
|
||||
console.error("Error generating unique numbers:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async findAllWithFilter(filter?: FilterQuery<ClaimRequestManagementModel>) {
|
||||
return await this.model.find(filter);
|
||||
}
|
||||
|
||||
async findByIdAndUpdate(
|
||||
id: string,
|
||||
updateDto: UpdateQuery<ClaimRequestManagementModel>,
|
||||
): Promise<ClaimRequestManagementModel | null> {
|
||||
return this.model.findByIdAndUpdate(id, updateDto, { new: true }).lean();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { InjectModel } from "@nestjs/mongoose";
|
||||
import { FilterQuery, Model, Types } from "mongoose";
|
||||
import { ClaimRequiredDocument } from "src/claim-request-management/entites/schema/claim-required-document.schema";
|
||||
|
||||
@Injectable()
|
||||
export class ClaimRequiredDocumentDbService {
|
||||
constructor(
|
||||
@InjectModel(ClaimRequiredDocument.name)
|
||||
private readonly model: Model<ClaimRequiredDocument>,
|
||||
) {}
|
||||
|
||||
async create(document: Partial<ClaimRequiredDocument>): Promise<ClaimRequiredDocument> {
|
||||
return await this.model.create(document);
|
||||
}
|
||||
|
||||
async findOne(
|
||||
filter: FilterQuery<ClaimRequiredDocument>,
|
||||
): Promise<ClaimRequiredDocument | null> {
|
||||
return await this.model.findOne(filter);
|
||||
}
|
||||
|
||||
async findAll(
|
||||
filter: FilterQuery<ClaimRequiredDocument>,
|
||||
): Promise<ClaimRequiredDocument[]> {
|
||||
return await this.model.find(filter);
|
||||
}
|
||||
|
||||
async findById(id: string): Promise<ClaimRequiredDocument | null> {
|
||||
return this.model.findById(id).lean();
|
||||
}
|
||||
|
||||
async findByClaimId(claimId: string): Promise<ClaimRequiredDocument[]> {
|
||||
return this.model.find({ claimId: new Types.ObjectId(claimId) });
|
||||
}
|
||||
|
||||
async delete(id: string): Promise<void> {
|
||||
await this.model.findByIdAndDelete(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { InjectModel } from "@nestjs/mongoose";
|
||||
import { FilterQuery, Model } from "mongoose";
|
||||
import { ClaimSignModel } from "src/claim-request-management/entites/schema/claim-sign";
|
||||
|
||||
@Injectable()
|
||||
export class ClaimSignDbService {
|
||||
constructor(
|
||||
@InjectModel(ClaimSignModel.name)
|
||||
private readonly claimSignService: Model<ClaimSignModel>,
|
||||
) {}
|
||||
|
||||
async create(claimSign: ClaimSignModel): Promise<ClaimSignModel> {
|
||||
return await this.claimSignService.create(claimSign);
|
||||
}
|
||||
|
||||
async findOne(filter: FilterQuery<ClaimSignModel>): Promise<ClaimSignModel> {
|
||||
return await this.claimSignService.findOne(filter);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { InjectModel } from "@nestjs/mongoose";
|
||||
import { Model, Types } from "mongoose";
|
||||
import { DamagePartImageModel } from "src/claim-request-management/entites/schema/damage-image-part.schema";
|
||||
|
||||
export class DamageImageDbService {
|
||||
constructor(
|
||||
@InjectModel(DamagePartImageModel.name)
|
||||
private readonly model: Model<DamagePartImageModel>,
|
||||
) {}
|
||||
|
||||
async create(image): Promise<DamagePartImageModel> {
|
||||
return await this.model.create(image);
|
||||
}
|
||||
|
||||
async findOne(id: string): Promise<DamagePartImageModel> {
|
||||
return await this.model.findById(new Types.ObjectId(id));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { InjectModel } from "@nestjs/mongoose";
|
||||
import { FilterQuery, Model } from "mongoose";
|
||||
import { ClaimFactorsImage } from "src/claim-request-management/entites/schema/factor-image.schema";
|
||||
|
||||
@Injectable()
|
||||
export class ClaimFactorsImageDbService {
|
||||
constructor(
|
||||
@InjectModel(ClaimFactorsImage.name)
|
||||
private readonly model: Model<ClaimFactorsImage>,
|
||||
) {}
|
||||
async create(image): Promise<ClaimFactorsImage> {
|
||||
return await this.model.create(image);
|
||||
}
|
||||
|
||||
async findOne(
|
||||
filter: FilterQuery<ClaimFactorsImage>,
|
||||
): Promise<ClaimFactorsImage> {
|
||||
return await this.model.findOne({ filter });
|
||||
}
|
||||
|
||||
async findById(id: string): Promise<ClaimFactorsImage | null> {
|
||||
return this.model.findById(id).lean();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { InjectModel } from "@nestjs/mongoose";
|
||||
import { FilterQuery, Model } from "mongoose";
|
||||
import { VideoCaptureModel } from "src/claim-request-management/entites/schema/video-capture.schema";
|
||||
|
||||
@Injectable()
|
||||
export class VideoCaptureDbService {
|
||||
constructor(
|
||||
@InjectModel(VideoCaptureModel.name)
|
||||
private readonly videoCapture: Model<VideoCaptureModel>,
|
||||
) {}
|
||||
async create(video): Promise<VideoCaptureModel> {
|
||||
return await this.videoCapture.create(video);
|
||||
}
|
||||
|
||||
async findOne(
|
||||
filter: FilterQuery<VideoCaptureModel>,
|
||||
): Promise<VideoCaptureModel> {
|
||||
return await this.videoCapture.findOne(filter);
|
||||
}
|
||||
|
||||
async findById(id: string): Promise<VideoCaptureModel | null> {
|
||||
return this.videoCapture.findById(id).lean();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose";
|
||||
import mongoose, { Types } from "mongoose";
|
||||
|
||||
@Schema({ versionKey: false })
|
||||
export class ActionUserModel extends mongoose.Document {
|
||||
@Prop({ required: true, type: Types.ObjectId })
|
||||
userId: Types.ObjectId;
|
||||
|
||||
@Prop({ required: true, type: Date })
|
||||
date: Date;
|
||||
}
|
||||
|
||||
export const ActionActorSchema = SchemaFactory.createForClass(ActionUserModel);
|
||||
@@ -0,0 +1,7 @@
|
||||
import { Prop, Schema } from "@nestjs/mongoose";
|
||||
|
||||
@Schema({ versionKey: false, _id: true })
|
||||
export class AiImagesModel {
|
||||
@Prop({ type: "array" })
|
||||
imagesAddress: string[];
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose";
|
||||
import mongoose, { Types } from "mongoose";
|
||||
|
||||
@Schema({ versionKey: false, collection: "car-green-cards" })
|
||||
export class CarGreenCardModel extends mongoose.Document {
|
||||
@Prop({ required: false, type: String })
|
||||
path?: string;
|
||||
|
||||
@Prop({ required: false, type: String })
|
||||
fileName?: string;
|
||||
|
||||
@Prop({ required: false, type: Types.ObjectId })
|
||||
claimId?: Types.ObjectId;
|
||||
}
|
||||
|
||||
export const CarGreenCardSchema =
|
||||
SchemaFactory.createForClass(CarGreenCardModel);
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Prop } from "@nestjs/mongoose";
|
||||
|
||||
export class CarDamagePartOtherModel {
|
||||
@Prop({
|
||||
format: "array",
|
||||
description: "please add items of json into array",
|
||||
example: [{ "حسگر درها": true }],
|
||||
})
|
||||
otherParts?: [];
|
||||
}
|
||||
|
||||
export class CarDamagePartModel {
|
||||
@Prop({ type: String })
|
||||
side: string;
|
||||
|
||||
@Prop({ type: String })
|
||||
part: string;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { Prop } from "@nestjs/mongoose";
|
||||
import mongoose, { Types } from "mongoose";
|
||||
import { ActionUserModel } from "./action-user.schema";
|
||||
|
||||
export class ClaimBaseModel extends mongoose.Document {
|
||||
@Prop()
|
||||
readonly _id: Types.ObjectId;
|
||||
|
||||
@Prop()
|
||||
readonly created: Date;
|
||||
|
||||
@Prop({
|
||||
required: false,
|
||||
type: ActionUserModel,
|
||||
})
|
||||
createdBy: ActionUserModel;
|
||||
|
||||
@Prop({ required: false })
|
||||
readonly updated: Date;
|
||||
|
||||
@Prop({
|
||||
required: false,
|
||||
type: [ActionUserModel],
|
||||
})
|
||||
updatedBy: ActionUserModel[];
|
||||
|
||||
@Prop()
|
||||
readonly deleted: boolean;
|
||||
}
|
||||
@@ -0,0 +1,330 @@
|
||||
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;
|
||||
}
|
||||
|
||||
export class ActorLockDetails {
|
||||
@Prop({ type: String })
|
||||
fullName?: string;
|
||||
|
||||
@Prop({ type: Types.ObjectId })
|
||||
actorId?: Types.ObjectId;
|
||||
}
|
||||
|
||||
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[];
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@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;
|
||||
|
||||
@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,
|
||||
);
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose";
|
||||
import { Types } from "mongoose";
|
||||
import { ClaimRequiredDocumentType } from "src/Types&Enums/claim-request-management/required-document-type.enum";
|
||||
|
||||
@Schema({ versionKey: false, collection: "claim-required-documents" })
|
||||
export class ClaimRequiredDocument {
|
||||
@Prop({ required: true, type: String })
|
||||
path: string;
|
||||
|
||||
@Prop({ required: true, type: String })
|
||||
fileName: string;
|
||||
|
||||
@Prop({ required: true, type: Types.ObjectId })
|
||||
claimId: Types.ObjectId;
|
||||
|
||||
@Prop({ required: true, enum: ClaimRequiredDocumentType })
|
||||
documentType: ClaimRequiredDocumentType;
|
||||
|
||||
@Prop({ default: () => new Date() })
|
||||
uploadedAt: Date;
|
||||
|
||||
_id?: Types.ObjectId;
|
||||
}
|
||||
|
||||
export const ClaimRequiredDocumentSchema =
|
||||
SchemaFactory.createForClass(ClaimRequiredDocument);
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
import { Schema, SchemaFactory } from "@nestjs/mongoose";
|
||||
import { UserSignModel } from "src/request-management/entities/schema/sign.schema";
|
||||
|
||||
@Schema({ collection: "claim-sign", versionKey: false })
|
||||
export class ClaimSignModel extends UserSignModel {}
|
||||
export const ClaimSignSchema = SchemaFactory.createForClass(ClaimSignModel);
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose";
|
||||
|
||||
export type DamagePartImage = DamagePartImageModel & Document;
|
||||
|
||||
@Schema({ versionKey: false, collection: "damage-part-image" })
|
||||
export class DamagePartImageModel {
|
||||
@Prop({ default: null })
|
||||
path: string | null = null;
|
||||
|
||||
@Prop({ default: null })
|
||||
fileName: string | null = null;
|
||||
|
||||
@Prop({ default: null })
|
||||
claimId: string = null;
|
||||
}
|
||||
|
||||
export const DamageImageModelSchema =
|
||||
SchemaFactory.createForClass(DamagePartImageModel);
|
||||
@@ -0,0 +1,28 @@
|
||||
import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose";
|
||||
import { Types } from "mongoose";
|
||||
|
||||
@Schema({ versionKey: false, collection: "claim-factors-image" })
|
||||
export class ClaimFactorsImage {
|
||||
@Prop({ required: true, type: String })
|
||||
path: string;
|
||||
|
||||
@Prop({ required: true, type: String })
|
||||
fileName: string;
|
||||
|
||||
@Prop({ required: true, type: Types.ObjectId })
|
||||
claimId: Types.ObjectId;
|
||||
|
||||
@Prop({ required: true, type: String })
|
||||
partId: string;
|
||||
|
||||
@Prop({ required: true, type: Object })
|
||||
partName: any;
|
||||
|
||||
@Prop({ default: () => new Date() })
|
||||
uploadedAt: Date;
|
||||
|
||||
_id?: Types.ObjectId;
|
||||
}
|
||||
|
||||
export const ClaimFactorsImageSchema =
|
||||
SchemaFactory.createForClass(ClaimFactorsImage);
|
||||
@@ -0,0 +1,38 @@
|
||||
import { Prop, Schema } from "@nestjs/mongoose";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
@Schema({ versionKey: false, _id: false })
|
||||
export class ImageRequiredModel {
|
||||
@Prop({ type: "array" })
|
||||
public aroundTheCar = [
|
||||
{ side: "left" },
|
||||
{ side: "back" },
|
||||
{ side: "front" },
|
||||
{ side: "right" },
|
||||
];
|
||||
|
||||
@Prop({ type: "array" })
|
||||
public selectPartOfCar = [];
|
||||
|
||||
@Prop({ type: "string" })
|
||||
public aiReportText: string;
|
||||
|
||||
constructor(claimFile: any[]) {
|
||||
this.aroundTheCar.forEach((a) => {
|
||||
Object.assign(a, {
|
||||
partId: uuidv4(),
|
||||
imageId: null,
|
||||
aiReport: {},
|
||||
upload: false,
|
||||
});
|
||||
});
|
||||
this.selectPartOfCar = claimFile.map((c, idx) =>
|
||||
Object.assign(c, {
|
||||
partId: uuidv4(),
|
||||
aiReport: {},
|
||||
imageId: null,
|
||||
upload: false,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose";
|
||||
import mongoose, { Types } from "mongoose";
|
||||
|
||||
@Schema({ versionKey: false, collection: "claim-video-capture" })
|
||||
export class VideoCaptureModel extends mongoose.Document {
|
||||
@Prop({ required: false, type: String })
|
||||
path?: string;
|
||||
|
||||
@Prop({ required: false, type: String })
|
||||
fileName?: string;
|
||||
|
||||
@Prop({ required: false, type: Types.ObjectId })
|
||||
claimId?: Types.ObjectId;
|
||||
}
|
||||
|
||||
export const VideoCaptureSchema =
|
||||
SchemaFactory.createForClass(VideoCaptureModel);
|
||||
181
src/claim-request-management/utils/car-part.json
Normal file
181
src/claim-request-management/utils/car-part.json
Normal file
@@ -0,0 +1,181 @@
|
||||
{
|
||||
"قاب موتور": true,
|
||||
"گلگیرهاتایرها": true,
|
||||
"دیسک ترمز": true,
|
||||
"لنت ترمز": true,
|
||||
"روغن ترمز": true,
|
||||
"ترمز دستی": true,
|
||||
"پیچ چرخها": true,
|
||||
"پیستون ترمز": true,
|
||||
"پدال ترمز": true,
|
||||
"شلنگهای ترمز": true,
|
||||
"سوزن هواگیر": true,
|
||||
"سامانه ABS": true,
|
||||
"پمپ ترمز": true,
|
||||
"کالیپر": true,
|
||||
"بوستر": true,
|
||||
"انواع سوپاپهای ترمز": true,
|
||||
"فنرهای نگهدارنده": true,
|
||||
"لنگر": true,
|
||||
"کفشک ترمز": true,
|
||||
"مخزن روغن ترمز": true,
|
||||
"واحد تقویتکننده هیدرولیکی": true,
|
||||
"پایه باتری": true,
|
||||
"کابل باتری": true,
|
||||
"سینی باتری": true,
|
||||
"سامانه مدیریت باتری": true,
|
||||
"دینام": true,
|
||||
"ترمینال سیمکشی باتری": true,
|
||||
"چراغهای جلو و عقب": true,
|
||||
"چراغهای مهشکن": true,
|
||||
"چراغهایی داخل داشبورد": true,
|
||||
"چراغ سقفی داخل کابین": true,
|
||||
"حسگر دنده اتوماتیک": true,
|
||||
"حسگر سرعت": true,
|
||||
"حسگر دمای مایع خنککننده": true,
|
||||
"حسگر ترمز ABS": true,
|
||||
"حسگر اکسیژن": true,
|
||||
"حسگر جریان هوا": true,
|
||||
"حسگر کیسه هوا": true,
|
||||
"حسگر روغن": true,
|
||||
"حسگر سوخت": true,
|
||||
"حسگر میللنگ": true,
|
||||
"حسگر میل بادامک": true,
|
||||
"حسگر کمربند ایمنی": true,
|
||||
"حسگر نور": true,
|
||||
"حسگر درها": true,
|
||||
"جعبه احتراق": true,
|
||||
"شمع": true,
|
||||
"دلکو": true,
|
||||
"کنترلگر زمان": true,
|
||||
"سیمهای اتصال": true,
|
||||
"سوپاپ مغناطیسی": true,
|
||||
"سیمپیچ احتراق": true,
|
||||
"وایر شمع": true,
|
||||
"رله فن": true,
|
||||
"سوئیچ درها": true,
|
||||
"سوئیچ استارت": true,
|
||||
"کلید شیشه بالابر": true,
|
||||
"سوئیچ قفل فرمان": true,
|
||||
"ترموستات": true,
|
||||
"تهویه": true,
|
||||
"موتور": true,
|
||||
"کف کابین": true,
|
||||
"ادوات داخل کابین": true,
|
||||
"اصلی": true,
|
||||
"دوربین دنده عقب": true,
|
||||
"دوربینهای 360 درجه": true,
|
||||
"صال به زمین": true,
|
||||
"سامانه قفل مرکزی": true,
|
||||
"اتصالات برقی درها": true,
|
||||
"ماژول کنترل ایربگ": true,
|
||||
"سامانه کنترل سرعت": true,
|
||||
"سامانه مدیریت موتور": true,
|
||||
"کروز کنترل": true,
|
||||
"سامانه ناوبری": true,
|
||||
"سوکتها": true,
|
||||
"سیستم قفل از راه دور": true,
|
||||
"رایانه جعبهدنده": true,
|
||||
"فیوزها": true,
|
||||
"بلوک سیلندر": true,
|
||||
"پوشش میللنگ": true,
|
||||
"پولی میللنگ": true,
|
||||
"میللنگ": true,
|
||||
"پولی پمپ آب": true,
|
||||
"تسمه پروانه": true,
|
||||
"پیستون": true,
|
||||
"تسمه دینام": true,
|
||||
"تسمه تایم": true,
|
||||
"توربو شارژ": true,
|
||||
"درپوش سوپاپ": true,
|
||||
"دسته موتور": true,
|
||||
"سرسیلندر": true,
|
||||
"سوپاپ پایت": true,
|
||||
"سوپاپ تهویه": true,
|
||||
"شاتون": true,
|
||||
"پین انگشتی": true,
|
||||
"بخاری": true,
|
||||
"میل بادامک": true,
|
||||
"لرزشگیر موتور": true,
|
||||
"فیلر": true,
|
||||
"جعبهدنده": true,
|
||||
"پوسته گیربکس": true,
|
||||
"چرخدندههای انتقال قدرت، جناحی، هرزگرد، سرعتسنج، چرخ لنگر، فرمان": true,
|
||||
"پمپ دنده": true,
|
||||
"دنده": true,
|
||||
"اهرم تعویض دنده": true,
|
||||
"دوشاخ دنده": true,
|
||||
"کوپلینگ دنده": true,
|
||||
"دیفرانسیل": true,
|
||||
"سیلندر": true,
|
||||
"فنر جعبهدنده": true,
|
||||
"محور جعبهدنده": true,
|
||||
"میلگاردان": true,
|
||||
"شفت خروجی": true,
|
||||
"پولوسها": true,
|
||||
"سامانه کلاچ": true,
|
||||
"کابل تعویض دنده": true,
|
||||
"فیلتر بنزین": true,
|
||||
"فیلتر هوا": true,
|
||||
"کاربراتور": true,
|
||||
"باک سوخت": true,
|
||||
"سیستم LPG": true,
|
||||
"کابل ساسات": true,
|
||||
"منیفولد ورودی": true,
|
||||
"جداکننده آب از سوخت": true,
|
||||
"پیل سوختی": true,
|
||||
"سیستم CNG": true,
|
||||
"پمپبنزین": true,
|
||||
"انژکتور": true,
|
||||
"بدنه دریچه گاز": true,
|
||||
"خنککننده سوخت": true,
|
||||
"رگلاتور": true,
|
||||
"ریل": true,
|
||||
"غربیلک فرمان": true,
|
||||
"بازوی فرمان": true,
|
||||
"جعبه فرمان": true,
|
||||
"دوک": true,
|
||||
"شفت فرمان": true,
|
||||
"سامانه فرمان خودکار": true,
|
||||
"اتصال جانبی": true,
|
||||
"اتصال میل موجگیر": true,
|
||||
"بازوی خمیده": true,
|
||||
"بازوی آزاد": true,
|
||||
"بازوی پیت – من": true,
|
||||
"بست و اتصالات": true,
|
||||
"سیبک فرمان": true,
|
||||
"کمکفنرها": true,
|
||||
"اتصالات تعادلی": true,
|
||||
"فنر": true,
|
||||
"محور خودرو": true,
|
||||
"عایق حرارتی": true,
|
||||
"گیرهها": true,
|
||||
"لوله اگزوز": true,
|
||||
"سپر حرارتی": true,
|
||||
"صداخفهکن": true,
|
||||
"رزیناتور": true,
|
||||
"کاتالیست": true,
|
||||
"حلقه فاصله": true,
|
||||
"انواع واشرها": true,
|
||||
"لولههای روغن": true,
|
||||
"کارتل روغن": true,
|
||||
"پمپ روغن": true,
|
||||
"واشر پمپ روغن": true,
|
||||
"صافی روغن": true,
|
||||
"فیلتر روغن": true,
|
||||
"تسمه فن": true,
|
||||
"تیغه فن": true,
|
||||
"واتر پمپ": true,
|
||||
"واشر پمپ آب": true,
|
||||
"دمنده هوا": true,
|
||||
"بوش فن": true,
|
||||
"مخزن": true,
|
||||
"درپوش فشار": true,
|
||||
"ترموستات": true,
|
||||
"پوشش فن": true,
|
||||
"کلاچ فن": true,
|
||||
"پروانه یا فن": true,
|
||||
"لولههای ورودی و خروجی آب": true,
|
||||
"زانویی آب": true,
|
||||
"شلنگ مایع خنککننده": true
|
||||
}
|
||||
Reference in New Issue
Block a user