Initial commit after migration to gitea

This commit is contained in:
2026-01-18 11:27:43 +03:30
parent a21039410c
commit ea4b8eb543
196 changed files with 45567 additions and 9 deletions

View File

@@ -0,0 +1,80 @@
import { UserObjectionDto } from "src/claim-request-management/dto/user-objection.dto";
import {
ClaimRequestManagementModel,
SubmitReply,
UserComment,
UserResendDocuments,
PriceDrop,
} from "src/claim-request-management/entites/schema/claim-request-management.schema";
export class ClaimPerIdRs {
requestDetail: any;
bankDamageUserInformation: {};
accidentLocation: {};
blameFile: any;
aiImages: any;
carPartDamage: any;
imageRequired: any;
carGreenCard: any;
nationalCodeOfInsurer: string;
otherParts: any;
sheba: any;
expertSubmitReply: any;
damageExpertResend: any;
damageExpertReply: SubmitReply;
damageExpertReplyFinal: SubmitReply;
lockFile: boolean;
videoCaptureId: any;
signDetails: UserComment;
lockTime: string | number | Date;
unlockTime: number | Date;
userResendDocuments: UserResendDocuments;
objection: UserObjectionDto;
dropPrice: PriceDrop;
type: string;
requiredDocuments: any;
constructor(request: ClaimRequestManagementModel) {
request.imageRequired.aroundTheCar = request.imageRequired.aroundTheCar.map(
(v) => {
//@ts-ignore
delete v.aiReport;
return v;
},
);
request.imageRequired.aroundTheCar =
request.imageRequired.selectPartOfCar.map((v) => {
//@ts-ignore
delete v.aiReport;
return v;
});
this.requestDetail = {
createdDate: request.createdAt.toLocaleDateString("fa-IR"),
createdTime: request.createdAt.toLocaleTimeString("fa-IR"),
status: request.claimStatus,
};
delete request.blameFile.actorsChecker;
this.bankDamageUserInformation = {
fullName: request.fullName,
numberOfSheba: request.sheba,
};
this.blameFile = request.blameFile;
this.videoCaptureId = request?.videoCaptureId;
this.damageExpertResend = request.damageExpertResend;
this.damageExpertReply = request.damageExpertReply;
this.damageExpertReplyFinal = request.damageExpertReplyFinal;
this.lockFile = request.lockFile;
this.lockTime = request.lockTime;
this.unlockTime = request.unlockTime;
this.userResendDocuments = request.userResendDocuments;
this.objection = request.objection as UserObjectionDto;
this.carPartDamage = request.carPartDamage;
this.imageRequired = request.imageRequired;
this.carGreenCard = request.carGreenCard;
this.nationalCodeOfInsurer = request.nationalCodeOfInsurer;
this.otherParts = request.otherParts;
this.sheba = request.sheba;
this.dropPrice = request.priceDrop;
this.type = request.blameFile?.type || "THIRD_PARTY"; // Include type field from blameFile
this.requiredDocuments = request.requiredDocuments;
}
}

View File

@@ -0,0 +1,22 @@
export class ClaimListDtoRs {
public data: any[];
constructor(claimFile) {
this.data = claimFile.map((i) => {
return {
requestId: i._id,
lockFile: i.isLocked,
claimStatus: i.claimStatus,
requestCode: i.blameFile?.requestNumber,
firstPartyCar:
i.blameFile.firstPartyDetails.firstPartyCarDetail.carName,
secondPartyCar:
i.blameFile.secondPartyDetails?.secondPartyCarDetail.carName,
date: new Date(i.createdAt).toLocaleDateString("fa-IR"),
time: new Date(i.createdAt).toLocaleTimeString("fa-IR"),
status: i.status,
effectedUserReply: i.effectedUserReply?.reply,
type: i.blameFile?.type || "THIRD_PARTY", // Include type field from blameFile
};
});
}
}

View File

@@ -0,0 +1,33 @@
import { ApiProperty } from "@nestjs/swagger";
import { Type } from "class-transformer";
import {
IsArray,
IsEnum,
IsOptional,
IsString,
ValidateNested,
} from "class-validator";
import { FactorStatus } from "src/Types&Enums/claim-request-management/factor-status.enum";
class FactorDecisionDto {
@ApiProperty()
@IsString()
partId: string;
@ApiProperty({ enum: [FactorStatus.APPROVED, FactorStatus.REJECTED] })
@IsEnum([FactorStatus.APPROVED, FactorStatus.REJECTED])
status: FactorStatus;
@ApiProperty({ required: false })
@IsOptional()
@IsString()
rejectionReason?: string;
}
export class FactorValidationDto {
@ApiProperty({ type: [FactorDecisionDto] })
@IsArray()
@ValidateNested({ each: true })
@Type(() => FactorDecisionDto)
decisions: FactorDecisionDto[];
}

View File

@@ -0,0 +1,97 @@
import { ApiProperty } from "@nestjs/swagger";
import { TypeOfDamage } from "src/Types&Enums/claim-request-management/type-of-damage.enum";
import { DaghiOption } from "src/Types&Enums/claim-request-management/daghi-option.enum";
export class CarPartDamageDto {
@ApiProperty({ type: String })
side: string;
@ApiProperty({ type: String })
part: string;
}
export class DaghiDetailsDto {
@ApiProperty({
required: true,
enum: DaghiOption,
description: "Daghi option: ارزش لوازم بازیافتی, تحویل داغی, فاقد ارزش, با احتساب داغی",
})
option: DaghiOption;
@ApiProperty({
required: false,
type: String,
description: "Price field required when option is 'ارزش لوازم بازیافتی'",
})
price?: string;
@ApiProperty({
required: false,
type: String,
description: "Branch ID required when option is 'تحویل داغی'",
})
branchId?: string;
}
export class PartsList {
@ApiProperty({ required: true, type: String })
partId: string;
@ApiProperty({ required: true, type: CarPartDamageDto })
carPartDamage: CarPartDamageDto;
@ApiProperty({ required: true, type: String })
typeOfDamage: TypeOfDamage;
@ApiProperty({ required: true, type: String })
price: string;
@ApiProperty({ required: true, type: String })
salary: string;
@ApiProperty({ required: true, type: String })
totalPayment: string;
@ApiProperty({ required: true, type: DaghiDetailsDto })
daghi: DaghiDetailsDto;
@ApiProperty({ required: true, type: Boolean })
factorNeeded: boolean;
}
export class ClaimSubmitReplyDto {
@ApiProperty({ required: true })
description: string;
@ApiProperty({ required: true, type: [PartsList] })
parts: PartsList[];
}
export class ResendCarPartsDto {
@ApiProperty({ required: true })
partId: string;
@ApiProperty({ required: true })
partName: string;
@ApiProperty({ required: false })
side?: string;
}
class InPersonDocuments {
NationalCertificate: string;
CarCertificate: string;
DrivingLicense: string;
CarGreenCard: string;
}
export class ClaimSubmitResendDto {
@ApiProperty({ required: true })
resendDescription: string;
@ApiProperty({ required: true, examples: InPersonDocuments })
resendDocuments: InPersonDocuments[];
@ApiProperty({ required: true, type: [ResendCarPartsDto] })
resendCarParts: ResendCarPartsDto[];
}

View File

@@ -0,0 +1,179 @@
import {
Body,
Controller,
Get,
Header,
Param,
Put,
Query,
Res,
UseGuards,
Headers,
Patch,
} from "@nestjs/common";
import {
ApiBearerAuth,
ApiBody,
ApiParam,
ApiQuery,
ApiTags,
} from "@nestjs/swagger";
import { LocalActorAuthGuard } from "src/auth/guards/actor-local.guard";
import { RolesGuard } from "src/auth/guards/role.guard";
import { ClientKey } from "src/decorators/clientKey.decorator";
import { Roles } from "src/decorators/roles.decorator";
import { CurrentUser } from "src/decorators/user.decorator";
import {
ClaimSubmitReplyDto,
ClaimSubmitResendDto,
} from "src/expert-claim/dto/reply.dto";
import { RoleEnum } from "src/Types&Enums/role.enum";
import { ParseJsonPipe } from "src/utils/pipes/parse-json.pipe";
import { ExpertClaimService } from "./expert-claim.service";
import { FactorValidationDto } from "./dto/factor-validation.dto";
@ApiTags("expert-claim-panel")
@Controller("expert-claim")
@ApiBearerAuth()
@UseGuards(LocalActorAuthGuard, RolesGuard)
@Roles(RoleEnum.DAMAGE_EXPERT)
export class ExpertClaimController {
constructor(private readonly expertClaimService: ExpertClaimService) {}
@Get()
async getAllClaimRequests(@CurrentUser() actor, @ClientKey() client) {
return await this.expertClaimService.getClaimRequestsListForExpert(actor);
}
@Get("/:id")
@ApiParam({ name: "id" })
@ApiQuery({
name: "updateDropPrice",
required: false,
description: "A stringified JSON object with price drop override values.",
})
async getClaimRequestPerId(
@Param("id") id: string,
@CurrentUser() currentUser,
@Query("updateDropPrice", new ParseJsonPipe()) priceDrop?: any,
) {
return await this.expertClaimService.requestPerId(
id,
currentUser,
priceDrop,
);
}
@Get("imageRequired/:id")
@ApiParam({ name: "id" })
async getImageRequired(@Param("id") id: string, @CurrentUser() currentUser) {
return await this.expertClaimService.imageRequired(id, currentUser);
}
@Get("required-documents/:id")
@ApiParam({ name: "id" })
async getRequiredDocuments(
@Param("id") id: string,
@CurrentUser() currentUser,
) {
return await this.expertClaimService.getRequiredDocuments(id, currentUser);
}
@Put("lock/:id")
async lockClaimRequest(@Param("id") requestId: string, @CurrentUser() actor) {
return await this.expertClaimService.lockClaimRequest(requestId, actor);
}
@Put("reply/submit/:id")
@ApiParam({ name: "id" })
async submitReplyRequest(
@Param("id") requestId,
@Body() body: ClaimSubmitReplyDto,
@CurrentUser() actor,
) {
return await this.expertClaimService.submitReplyRequest(
requestId,
body,
actor,
);
}
@Put("resend/submit/:id")
@ApiParam({ name: "id" })
async submitResend(
@Param("id") requestId,
@Body() body: ClaimSubmitResendDto,
@CurrentUser() actor,
) {
return await this.expertClaimService.submitResend(
requestId,
body,
actor.sub,
);
}
@ApiQuery({
name: "query",
enum: ["car-capture", "accident"],
required: true,
})
@Get("stream/:id/video")
@Header("Accept-Ranges", "bytes")
@Header("Content-Type", "video/mp4")
async claimStream(
@Headers() headers,
@Param("id") id: string,
@Query("query") query: "car-capture" | "accident",
@Res() res,
) {
return this.expertClaimService.streamService(id, query, res, headers);
}
@ApiQuery({
name: "query",
enum: ["car-capture", "accident"],
required: true,
})
@Get("link/:id/video")
@ApiParam({ name: "id" })
async getClaimVideoLink(
@Param("id") id: string,
@Query("query") query: "car-capture" | "accident",
) {
return this.expertClaimService.getVideoLink(id, query);
}
@Get("stream/:id/voice")
@ApiParam({ name: "id" })
async getClaimVoiceLink(@Param("id") id: string) {
return await this.expertClaimService.getVoiceLink(id);
}
@Patch("validate-factors/:claimId")
@ApiParam({ name: "claimId" })
@ApiBody({ type: FactorValidationDto })
@Roles(RoleEnum.DAMAGE_EXPERT)
async validateFactors(
@Param("claimId") claimId: string,
@Body() validationData: FactorValidationDto,
@CurrentUser() user,
) {
return this.expertClaimService.validateClaimFactors(
claimId,
validationData.decisions,
user.sub,
);
}
@ApiParam({ name: "id" })
@Patch(":id/visit")
async inPersonVisit(@Param("id") requestId: string, @CurrentUser() actor) {
return await this.expertClaimService.inPersonVisit(requestId, actor);
}
@Get("branches/:insuranceId")
@ApiParam({ name: "insuranceId" })
async getInsuranceBranches(@Param("insuranceId") insuranceId: string) {
return await this.expertClaimService.retrieveInsuranceBranches(insuranceId);
}
}

View File

@@ -0,0 +1,40 @@
import { HttpModule } from "@nestjs/axios";
import { Module } from "@nestjs/common";
import { MongooseModule } from "@nestjs/mongoose";
import { AiModule } from "src/ai/ai.module";
import { AuthModule } from "src/auth/auth.module";
import { ClaimRequestManagementModule } from "src/claim-request-management/claim-request-management.module";
import { ClaimFactorsImageDbService } from "src/claim-request-management/entites/db-service/factor-image.db.service";
import {
ClaimFactorsImage,
ClaimFactorsImageSchema,
} from "src/claim-request-management/entites/schema/factor-image.schema";
import { ClientModule } from "src/client/client.module";
import { ExpertBlameModule } from "src/expert-blame/expert-blame.module";
import { RequestManagementModule } from "src/request-management/request-management.module";
import { SandHubModule } from "src/sand-hub/sand-hub.module";
import { UsersModule } from "src/users/users.module";
import { ExpertClaimController } from "./expert-claim.controller";
import { ExpertClaimService } from "./expert-claim.service";
@Module({
imports: [
HttpModule,
SandHubModule,
MongooseModule.forFeature([
{ name: ClaimFactorsImage.name, schema: ClaimFactorsImageSchema },
]),
AuthModule,
ExpertBlameModule,
ClaimRequestManagementModule,
ExpertBlameModule,
AiModule,
RequestManagementModule,
UsersModule,
ClientModule,
],
controllers: [ExpertClaimController],
providers: [ExpertClaimService, ClaimFactorsImageDbService],
exports: [ClaimFactorsImageDbService, ExpertClaimService],
})
export class ExpertClaimModule {}

File diff suppressed because it is too large Load Diff