forked from Yara724/api
Added API for externalAPI, added env for clients
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { join } from "node:path";
|
||||
import { APP_INTERCEPTOR, APP_PIPE } from "@nestjs/core";
|
||||
import { Module, ValidationPipe } from "@nestjs/common";
|
||||
import { ConfigModule, ConfigService } from "@nestjs/config";
|
||||
import { Module } from "@nestjs/common";
|
||||
import { ConfigService } from "@nestjs/config";
|
||||
import { UnicodeDigitsNormalizeInterceptor } from "./common/interceptors/unicode-digits-normalize.interceptor";
|
||||
import { MongooseModule } from "@nestjs/mongoose";
|
||||
import { ServeStaticModule } from "@nestjs/serve-static";
|
||||
@@ -24,79 +24,18 @@ import { applyIranFaTimestampPlugin } from "./helpers/mongoose-fa-timestamps.plu
|
||||
import { CronModule } from "./utils/cron/cron.module";
|
||||
import { WorkflowStepManagementModule } from "./workflow-step-management/workflow-step-management.module";
|
||||
import { ExpertInitiatedModule } from "./expert-initiated/expert-initiated.module";
|
||||
import * as Joi from "joi";
|
||||
import { DatabaseModule } from "./core/database/database.module";
|
||||
import { AppConfigModule } from "./core/config/config.module";
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
ConfigModule.forRoot({
|
||||
isGlobal: true,
|
||||
validationSchema: Joi.object({
|
||||
NODE_ENV: Joi.string()
|
||||
.valid("development", "production")
|
||||
.default("development"),
|
||||
PORT: Joi.number().port().default(9001),
|
||||
URL: Joi.string().uri().required(),
|
||||
BASE_URL_DEV: Joi.string()
|
||||
.uri()
|
||||
.when("NODE_ENV", {
|
||||
is: Joi.string().valid("development"),
|
||||
then: Joi.required(),
|
||||
otherwise: Joi.optional(),
|
||||
}),
|
||||
SWAGGER_USER_DEV: Joi.string().when("NODE_ENV", {
|
||||
is: Joi.string().valid("development"),
|
||||
then: Joi.required(),
|
||||
otherwise: Joi.optional(),
|
||||
}),
|
||||
SWAGGER_PASSWORD_DEV: Joi.string().when("NODE_ENV", {
|
||||
is: Joi.string().valid("development"),
|
||||
then: Joi.required(),
|
||||
otherwise: Joi.optional(),
|
||||
}),
|
||||
MONGO_HOST: Joi.string().required(),
|
||||
MONGO_PORT: Joi.number().port().required(),
|
||||
MONGO_USER: Joi.string().required(),
|
||||
MONGO_PASS: Joi.string().required(),
|
||||
MONGO_DB_NAME: Joi.string().required(),
|
||||
JWT_SECRET: Joi.string().required(),
|
||||
SANHUB_BASE_URL: Joi.string().uri(),
|
||||
SANHUB_URL_LOGIN: Joi.string().uri(),
|
||||
SANHUB_USERNAME: Joi.string(),
|
||||
SANHUB_PASSWORD: Joi.string(),
|
||||
AI_URL: Joi.string().uri(),
|
||||
AI_URL_V2: Joi.string().uri(),
|
||||
AI_USERNAME: Joi.string(),
|
||||
AI_PASSWORD: Joi.string(),
|
||||
SMS_PROVIDER: Joi.string()
|
||||
.valid("kavenegar", "parsian")
|
||||
.default("kavenegar"),
|
||||
SMS_API_KEY: Joi.string(),
|
||||
AUTH_SMS_TEMPLATE: Joi.string(),
|
||||
EXP_OTP_TIME: Joi.number(),
|
||||
}),
|
||||
}),
|
||||
AppConfigModule,
|
||||
DatabaseModule,
|
||||
CronModule,
|
||||
ServeStaticModule.forRoot({
|
||||
rootPath: join(__dirname, "..", "files"),
|
||||
serveRoot: "/files",
|
||||
}),
|
||||
MongooseModule.forRootAsync({
|
||||
inject: [ConfigService],
|
||||
useFactory: (configService: ConfigService) => {
|
||||
return {
|
||||
uri: `mongodb://${configService.get<string>("MONGO_USER")}:${configService.get<string>("MONGO_PASS")}@${configService.get<string>("MONGO_HOST")}:${configService.get<string>("MONGO_PORT")}/${configService.get<string>("MONGO_DB_NAME")}?authSource=admin&${configService.get<string>("MONGO_OPTIONS")}`,
|
||||
tls: configService.get<string>("MONGO_TLS") === "true",
|
||||
tlsAllowInvalidCertificates:
|
||||
configService.get<string>("MONGO_TLS_ALLOW_INVALID_CERTS") ===
|
||||
"true",
|
||||
autoIndex: configService.get<string>("NODE_ENV") !== "production",
|
||||
connectionFactory: (connection) => {
|
||||
applyIranFaTimestampPlugin(connection);
|
||||
return connection;
|
||||
},
|
||||
};
|
||||
},
|
||||
}),
|
||||
UsersModule,
|
||||
AuthModule,
|
||||
ClientModule,
|
||||
|
||||
@@ -1,17 +1,24 @@
|
||||
import { Body, Controller, Get, Post, UseGuards } from "@nestjs/common";
|
||||
import { ApiBearerAuth, ApiTags } from "@nestjs/swagger";
|
||||
import { GlobalGuard } from "src/auth/guards/global.guard";
|
||||
import { RolesGuard } from "src/auth/guards/role.guard";
|
||||
import { Roles } from "src/decorators/roles.decorator";
|
||||
import { Body, Controller, Get, Patch, Post } from "@nestjs/common";
|
||||
import {
|
||||
ApiBody,
|
||||
ApiOperation,
|
||||
ApiResponse,
|
||||
ApiTags,
|
||||
} from "@nestjs/swagger";
|
||||
import { CurrentUser } from "src/decorators/user.decorator";
|
||||
import { RoleEnum } from "src/Types&Enums/role.enum";
|
||||
import { SystemSettingsResponseDto } from "src/system-settings/dto/system-settings.dto";
|
||||
import { SystemSettingsService } from "src/system-settings/system-settings.service";
|
||||
import { ClientService } from "./client.service";
|
||||
import { ClientDto } from "./dto/create-client.dto";
|
||||
import { SetExternalInquiriesLiveDto } from "./dto/external-inquiries-live.dto";
|
||||
|
||||
@Controller("client")
|
||||
@ApiTags("client-management")
|
||||
export class ClientController {
|
||||
constructor(private readonly clientService: ClientService) {}
|
||||
constructor(
|
||||
private readonly clientService: ClientService,
|
||||
private readonly systemSettingsService: SystemSettingsService,
|
||||
) {}
|
||||
|
||||
@Post()
|
||||
async addClient(@Body() client: ClientDto) {
|
||||
@@ -27,4 +34,33 @@ export class ClientController {
|
||||
async getClientList(@CurrentUser() user) {
|
||||
return await this.clientService.getClientList();
|
||||
}
|
||||
|
||||
/** Toggle SandHub/Tejarat live HTTP vs mock inquiries (`system_settings.externalApis.sandHubUseLiveApi`). */
|
||||
@Patch("external-inquiries-live")
|
||||
@ApiOperation({
|
||||
summary: "Enable or disable live external inquiries",
|
||||
description:
|
||||
"Updates `system_settings.externalApis.sandHubUseLiveApi`. No auth required. Use the request examples below to switch between live Tejarat/SandHub HTTP and offline mock mode.",
|
||||
})
|
||||
@ApiBody({
|
||||
type: SetExternalInquiriesLiveDto,
|
||||
examples: {
|
||||
enableLive: {
|
||||
summary: "Enable live inquiries",
|
||||
description: "Call real SandHub/Tejarat HTTP APIs.",
|
||||
value: { enabled: true },
|
||||
},
|
||||
disableLive: {
|
||||
summary: "Disable live inquiries (mock mode)",
|
||||
description: "Use mocked inquiry responses; flows continue without external connectivity.",
|
||||
value: { enabled: false },
|
||||
},
|
||||
},
|
||||
})
|
||||
@ApiResponse({ status: 200, type: SystemSettingsResponseDto })
|
||||
async setExternalInquiriesLive(@Body() body?: SetExternalInquiriesLiveDto) {
|
||||
return this.systemSettingsService.updateSettings({
|
||||
externalApis: { sandHubUseLiveApi: body?.enabled === true },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
import { MongooseModule } from "@nestjs/mongoose";
|
||||
import { SystemSettingsModule } from "src/system-settings/system-settings.module";
|
||||
import { ClientController } from "./client.controller";
|
||||
import { ClientPanelController } from "./client-panel.controller";
|
||||
import { ClientService } from "./client.service";
|
||||
@@ -10,6 +11,7 @@ import { ClientDbSchema, ClientModel } from "./entities/schema/client.schema";
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
SystemSettingsModule,
|
||||
MongooseModule.forFeature([
|
||||
{ name: ClientModel.name, schema: ClientDbSchema },
|
||||
{
|
||||
|
||||
@@ -142,6 +142,38 @@ export class ClientService {
|
||||
return await this.clientDbService.find({ clientCode: companyCode });
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a client by insurer company code from an external inquiry.
|
||||
* Creates the client when missing so inquiry flows don't fail on unknown codes.
|
||||
*/
|
||||
async findOrCreateClientByCompanyCode(
|
||||
companyCode: number | string | null | undefined,
|
||||
companyName: string | null | undefined,
|
||||
) {
|
||||
const name = typeof companyName === "string" ? companyName.trim() : "";
|
||||
const code = Number(companyCode);
|
||||
if (!name || !Number.isFinite(code)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let client = await this.clientDbService.find({ clientCode: code });
|
||||
if (client) return client;
|
||||
|
||||
try {
|
||||
await this.addClient({
|
||||
clientName: { persian: name, english: null },
|
||||
clientCode: code,
|
||||
useExpertMode: "legal",
|
||||
});
|
||||
} catch (err) {
|
||||
client = await this.clientDbService.find({ clientCode: code });
|
||||
if (client) return client;
|
||||
throw err;
|
||||
}
|
||||
|
||||
return this.clientDbService.find({ clientCode: code });
|
||||
}
|
||||
|
||||
async getClients(): Promise<ClientDtoRs[]> {
|
||||
const clients = await this.clientDbService.findAll();
|
||||
const show = clients.map((c) => new ClientDtoRs(c));
|
||||
|
||||
10
src/client/dto/external-inquiries-live.dto.ts
Normal file
10
src/client/dto/external-inquiries-live.dto.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { ApiProperty } from "@nestjs/swagger";
|
||||
|
||||
export class SetExternalInquiriesLiveDto {
|
||||
@ApiProperty({
|
||||
description:
|
||||
"When true, SandHub/Tejarat live HTTP inquiries run. When false, mocked inquiry data is used.",
|
||||
example: true,
|
||||
})
|
||||
enabled: boolean;
|
||||
}
|
||||
14
src/core/config/config.module.ts
Normal file
14
src/core/config/config.module.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
import { ConfigModule } from "@nestjs/config";
|
||||
import { validate } from "./config.validation";
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
ConfigModule.forRoot({
|
||||
isGlobal: true,
|
||||
expandVariables: true,
|
||||
validate,
|
||||
}),
|
||||
],
|
||||
})
|
||||
export class AppConfigModule {}
|
||||
75
src/core/config/config.schema.ts
Normal file
75
src/core/config/config.schema.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import {
|
||||
IsBooleanString,
|
||||
IsEnum,
|
||||
IsNumber,
|
||||
IsPositive,
|
||||
IsString,
|
||||
IsUrl,
|
||||
Matches,
|
||||
Max,
|
||||
Min,
|
||||
MinLength,
|
||||
} from "class-validator";
|
||||
import { StringValue } from "ms";
|
||||
|
||||
export enum Environment {
|
||||
Development = "development",
|
||||
Production = "production",
|
||||
}
|
||||
|
||||
export class EnvironmentVariables {
|
||||
@IsEnum(Environment, {
|
||||
message: "NODE_ENV should be development or production",
|
||||
})
|
||||
NODE_ENV: Environment;
|
||||
// --------------------------------------------------------- //
|
||||
@IsNumber(
|
||||
{
|
||||
allowNaN: false,
|
||||
allowInfinity: false,
|
||||
},
|
||||
{
|
||||
message: "PORT must be a valid number",
|
||||
},
|
||||
)
|
||||
@IsPositive({ message: "PORT must be positive" })
|
||||
@Min(0, { message: "PORT must be between 0 and 65535" })
|
||||
@Max(65535, { message: "PORT must be between 0 and 65535" })
|
||||
PORT: number;
|
||||
// --------------------------------------------------------- //
|
||||
@IsString({ message: "MONGO_URI must be string" })
|
||||
@IsUrl(
|
||||
{
|
||||
require_tld: false,
|
||||
protocols: ["mongodb", "mongodb+srv"],
|
||||
},
|
||||
{
|
||||
message: "MONGO_URI must be in the correct format (mongodb://...)",
|
||||
},
|
||||
)
|
||||
MONGO_URI: string;
|
||||
// --------------------------------------------------------- //
|
||||
@IsBooleanString({ message: "MONGO_TLS must be boolean" })
|
||||
MONGO_TLS: string;
|
||||
// --------------------------------------------------------- //
|
||||
@IsBooleanString({ message: "MONGO_TLS_ALLOW_INVALID_CERTS must be boolean" })
|
||||
MONGO_TLS_ALLOW_INVALID_CERTS: string;
|
||||
// --------------------------------------------------------- //
|
||||
@IsString({ message: "JWT_SECRET must be string" })
|
||||
@MinLength(32, {
|
||||
message: "JWT_SECRET must be at least 32 characters",
|
||||
})
|
||||
JWT_SECRET: string;
|
||||
// --------------------------------------------------------- //
|
||||
@Matches(/^\d+(ms|s|m|h|d|w|y)$/, {
|
||||
message: "JWT_EXPIRY must be in the correct format",
|
||||
})
|
||||
JWT_EXPIRY: StringValue;
|
||||
// --------------------------------------------------------- //
|
||||
// @IsString({ message: "HASH_PEPPER must be string" })
|
||||
// @MinLength(32, {
|
||||
// message: "HASH_PEPPER must be at least 32 characters",
|
||||
// })
|
||||
// HASH_PEPPER: string;
|
||||
// --------------------------------------------------------- //
|
||||
}
|
||||
23
src/core/config/config.validation.ts
Normal file
23
src/core/config/config.validation.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { plainToInstance } from "class-transformer";
|
||||
import { validateSync } from "class-validator";
|
||||
import { EnvironmentVariables } from "./config.schema";
|
||||
|
||||
export function validate(config: Record<string, unknown>) {
|
||||
const validatedConfig = plainToInstance(EnvironmentVariables, config, {
|
||||
enableImplicitConversion: true,
|
||||
});
|
||||
|
||||
const errors = validateSync(validatedConfig, {
|
||||
skipMissingProperties: false,
|
||||
});
|
||||
|
||||
if (errors.length > 0) {
|
||||
const messages = errors
|
||||
.flatMap((error) => Object.values(error.constraints ?? {}))
|
||||
.join("\n");
|
||||
|
||||
throw new Error(`Environment validation failed:\n${messages}`);
|
||||
}
|
||||
|
||||
return validatedConfig;
|
||||
}
|
||||
19
src/core/database/database.module.ts
Normal file
19
src/core/database/database.module.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
import { ConfigService } from "@nestjs/config";
|
||||
import { MongooseModule } from "@nestjs/mongoose";
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
MongooseModule.forRootAsync({
|
||||
inject: [ConfigService],
|
||||
useFactory: (configService: ConfigService) => ({
|
||||
uri: configService.get<string>("MONGO_URI"),
|
||||
tls: configService.get<string>("MONGO_TLS") === "true",
|
||||
tlsAllowInvalidCertificates:
|
||||
configService.get<string>("MONGO_TLS_ALLOW_INVALID_CERTS") === "true",
|
||||
autoIndex: configService.get<string>("NODE_ENV") !== "production",
|
||||
}),
|
||||
}),
|
||||
],
|
||||
})
|
||||
export class DatabaseModule {}
|
||||
0
src/core/database/plugins/iran-timestamp.plugin.ts
Normal file
0
src/core/database/plugins/iran-timestamp.plugin.ts
Normal file
@@ -1160,24 +1160,16 @@ export class RequestManagementService {
|
||||
);
|
||||
}
|
||||
const companyCode = inquiryMapped?.CompanyCode;
|
||||
let client =
|
||||
await this.clientService.findClientWithCompanyCode(+companyCode);
|
||||
|
||||
const client = await this.clientService.findOrCreateClientByCompanyCode(
|
||||
companyCode,
|
||||
clientName,
|
||||
);
|
||||
if (!client) {
|
||||
await this.clientService.addClient({
|
||||
clientName: {
|
||||
persian: clientName,
|
||||
english: null,
|
||||
},
|
||||
clientCode: Number(companyCode),
|
||||
useExpertMode: "legal",
|
||||
});
|
||||
throw new BadRequestException(
|
||||
`CompanyCode missing or invalid in inquiry response`,
|
||||
);
|
||||
}
|
||||
|
||||
// if (!client) {
|
||||
// throw new HttpException("Client not found", HttpStatus.CONFLICT);
|
||||
// }
|
||||
|
||||
// Persist inquiry/body data into new model
|
||||
if (!party.person) party.person = {} as any;
|
||||
const resolvedClientId =
|
||||
@@ -1286,27 +1278,13 @@ export class RequestManagementService {
|
||||
const carBodyCompanyCode = m.companyId ?? m.CompanyCode;
|
||||
const carBodyCompanyName = m.CompanyName ?? m.companyPersianName;
|
||||
|
||||
if (carBodyCompanyCode) {
|
||||
let carBodyClient: any =
|
||||
await this.clientService.findClientWithCompanyCode(
|
||||
Number(carBodyCompanyCode),
|
||||
if (carBodyCompanyCode && carBodyCompanyName) {
|
||||
const carBodyClient =
|
||||
await this.clientService.findOrCreateClientByCompanyCode(
|
||||
carBodyCompanyCode,
|
||||
carBodyCompanyName,
|
||||
);
|
||||
|
||||
if (!carBodyClient && carBodyCompanyName) {
|
||||
await this.clientService.addClient({
|
||||
clientName: {
|
||||
persian: carBodyCompanyName,
|
||||
english: null,
|
||||
},
|
||||
clientCode: Number(carBodyCompanyCode),
|
||||
useExpertMode: "legal",
|
||||
});
|
||||
// Re-fetch after creation so we get the actual document with _id
|
||||
carBodyClient = await this.clientService.findClientWithCompanyCode(
|
||||
Number(carBodyCompanyCode),
|
||||
);
|
||||
}
|
||||
|
||||
const carBodyClientId =
|
||||
(carBodyClient as any)?._id ?? (carBodyClient as any)?._doc?._id;
|
||||
|
||||
@@ -2075,8 +2053,10 @@ export class RequestManagementService {
|
||||
const clientName = sandHubReport?.CompanyName;
|
||||
const companyCode = sandHubReport?.CompanyCode;
|
||||
|
||||
const client =
|
||||
await this.clientService.findClientWithCompanyCode(+companyCode);
|
||||
const client = await this.clientService.findOrCreateClientByCompanyCode(
|
||||
companyCode,
|
||||
clientName,
|
||||
);
|
||||
|
||||
if (!client) {
|
||||
throw new HttpException("Client not found", HttpStatus.CONFLICT);
|
||||
@@ -5021,7 +5001,10 @@ export class RequestManagementService {
|
||||
sandHubReport?.CompanyName || sandHubReport?.LastCompanyName;
|
||||
const companyCode = sandHubReport?.CompanyCode;
|
||||
const client = companyCode
|
||||
? await this.clientService.findClientWithCompanyCode(+companyCode)
|
||||
? await this.clientService.findOrCreateClientByCompanyCode(
|
||||
companyCode,
|
||||
clientName,
|
||||
)
|
||||
: await this.clientService.findOne({ clientName });
|
||||
if (!client) {
|
||||
throw new NotFoundException(
|
||||
@@ -5228,7 +5211,10 @@ export class RequestManagementService {
|
||||
sandHubReport?.CompanyName || sandHubReport?.LastCompanyName;
|
||||
const companyCode = sandHubReport?.CompanyCode;
|
||||
const client = companyCode
|
||||
? await this.clientService.findClientWithCompanyCode(+companyCode)
|
||||
? await this.clientService.findOrCreateClientByCompanyCode(
|
||||
companyCode,
|
||||
clientName,
|
||||
)
|
||||
: await this.clientService.findOne({ clientName });
|
||||
if (!client) {
|
||||
throw new NotFoundException(
|
||||
@@ -5834,7 +5820,10 @@ export class RequestManagementService {
|
||||
|
||||
// Try to find client by company code first (more reliable)
|
||||
const client = companyCode
|
||||
? await this.clientService.findClientWithCompanyCode(+companyCode)
|
||||
? await this.clientService.findOrCreateClientByCompanyCode(
|
||||
companyCode,
|
||||
clientName,
|
||||
)
|
||||
: await this.clientService.findOne({ clientName: clientName });
|
||||
|
||||
if (!client) {
|
||||
@@ -5898,7 +5887,10 @@ export class RequestManagementService {
|
||||
|
||||
// Try to find client by company code first (more reliable)
|
||||
const client = companyCode
|
||||
? await this.clientService.findClientWithCompanyCode(+companyCode)
|
||||
? await this.clientService.findOrCreateClientByCompanyCode(
|
||||
companyCode,
|
||||
clientName,
|
||||
)
|
||||
: await this.clientService.findOne({ clientName: clientName });
|
||||
|
||||
if (!client) {
|
||||
@@ -6168,7 +6160,10 @@ export class RequestManagementService {
|
||||
|
||||
// Try to find client by company code first (more reliable)
|
||||
const client = companyCode
|
||||
? await this.clientService.findClientWithCompanyCode(+companyCode)
|
||||
? await this.clientService.findOrCreateClientByCompanyCode(
|
||||
companyCode,
|
||||
clientName,
|
||||
)
|
||||
: await this.clientService.findOne({ clientName: clientName });
|
||||
|
||||
if (!client) {
|
||||
|
||||
@@ -40,40 +40,49 @@ export class SandHubService {
|
||||
return this.systemSettingsService.isSandHubLiveEnabled();
|
||||
}
|
||||
|
||||
/** Tenant-specific company fields for mocked external inquiries (MOCK_INQUIRY_COMPANY_*). */
|
||||
private getMockInquiryCompanyId(): string {
|
||||
return process.env.CLIENT_ID ?? "15";
|
||||
}
|
||||
|
||||
private getMockInquiryCompanyName(): string {
|
||||
return process.env.CLIENT_NAME ?? "بیمه سامان";
|
||||
}
|
||||
|
||||
/** Fixed plate/insurance inquiry payload used everywhere we mock block-inquiry style APIs. */
|
||||
private getDefaultMockPlateInquiryRaw(): Record<string, unknown> {
|
||||
return {
|
||||
PrntPlcyCmpDocNo: "1403/1143-70591/200/35",
|
||||
MapTypNam: "پرايد هاچ بک -111",
|
||||
MtrNum: "5215907",
|
||||
ShsNum: "NAS431100E5798656",
|
||||
DisFnYrNum: "0",
|
||||
DisLfYrNum: "0",
|
||||
DisPrsnYrNum: "0",
|
||||
DisPrsnYrPrcnt: "0",
|
||||
DisFnYrPrcnt: "0",
|
||||
DisLfYrPrcnt: "0",
|
||||
vin: "IRPC941V2BD798656",
|
||||
PrntPlcyCmpDocNo: "1404/1143-70591/200/123",
|
||||
MapTypNam: "فائو ( FAW )",
|
||||
MtrNum: "TZ196XYAP223A210074",
|
||||
ShsNum: "LFP8C7PC3R1K12157",
|
||||
DisFnYrNum: null,
|
||||
DisLfYrNum: null,
|
||||
DisPrsnYrNum: null,
|
||||
DisPrsnYrPrcnt: null,
|
||||
DisFnYrPrcnt: "5",
|
||||
DisLfYrPrcnt: "5",
|
||||
vin: "LFP8C7PC3R1K12157",
|
||||
MapVehicleSystemName: "ثبت نشده",
|
||||
LfCvrCptl: 0,
|
||||
FnCvrCptl: 0,
|
||||
PrsnCvrCptl: 0,
|
||||
VehicleSystemCode: 1,
|
||||
EdrsJson: '[{"id":1,"Dsc":" الحاقيه توضيحات ندارد"}]',
|
||||
EdrsJson: "",
|
||||
PersonCvrCptl: 12000000000,
|
||||
LifeCvrCptl: 16000000000,
|
||||
FinancialCvrCptl: 4000000000,
|
||||
CarGroupCode: 3,
|
||||
CylCnt: 4,
|
||||
LastCompanyDocumentNumber: "03/1031/2835/1001/662",
|
||||
LastCompanyDocumentNumber: "31/3100/03/18350",
|
||||
UsageCode: "8",
|
||||
MapUsageCode: 1,
|
||||
MapUsageName: "شخصي",
|
||||
Plk1: 59,
|
||||
Plk2: 16,
|
||||
Plk3: 419,
|
||||
PlkSrl: 78,
|
||||
PrintEndorsCompanyDocumentNumber: "بيمه نامه الحاقيه ندارد.",
|
||||
Plk1: 16,
|
||||
Plk2: 12,
|
||||
Plk3: 498,
|
||||
PlkSrl: 60,
|
||||
PrintEndorsCompanyDocumentNumber: "",
|
||||
EndorseDate: null,
|
||||
InsuranceFullName: null,
|
||||
SystemField: "سايپا",
|
||||
@@ -81,12 +90,12 @@ export class SandHubService {
|
||||
UsageField: "سواري",
|
||||
MainColorField: "سفيد",
|
||||
SecondColorField: "سفيد شيري",
|
||||
ModelField: "1394",
|
||||
ModelField: "2024",
|
||||
CapacityField: "جمعا 4 نفر",
|
||||
CylinderNumberField: "4",
|
||||
EngineNumberField: "5215907",
|
||||
ChassisNumberField: "NAS431100E5798656",
|
||||
VinNumberField: "IRPC941V2BD798656",
|
||||
ChassisNumberField: "LFP8C7PC3R1K12157",
|
||||
VinNumberField: "LFP8C7PC3R1K12157",
|
||||
InstallDateField: "1403/03/01",
|
||||
AxelNumberField: "2",
|
||||
WheelNumberField: "4",
|
||||
@@ -107,7 +116,7 @@ export class SandHubService {
|
||||
SystemCodeCii: 0,
|
||||
SystemNameCii: "ثبت نشده",
|
||||
TypeCodeCii: 12189,
|
||||
TypeNameCii: "پرايد هاچ بک -111",
|
||||
TypeNameCii: "فائو ( FAW )",
|
||||
UsageNameCii: "سواري",
|
||||
UsageCodeCii: 1,
|
||||
ModelCii: 1394,
|
||||
@@ -116,6 +125,47 @@ export class SandHubService {
|
||||
};
|
||||
}
|
||||
|
||||
private getDefaultMockCarBodyInquiryRaw(
|
||||
userDetail: SandHubDetailDto,
|
||||
): Record<string, unknown> {
|
||||
const companyId = Number(this.getMockInquiryCompanyId());
|
||||
|
||||
return {
|
||||
data: {
|
||||
id: 70016075946,
|
||||
printNumber: "1405/1143-70591/220/1/0",
|
||||
companyId: Number.isNaN(companyId) ? 15 : companyId,
|
||||
companyName: this.getMockInquiryCompanyName(),
|
||||
beginDate: "1405/01/17",
|
||||
endDate: "1406/01/17",
|
||||
issueDate: "1405/01/16",
|
||||
hasEndorsement: null,
|
||||
motorNumber: "TZ196XYAP223A210074",
|
||||
chassisNumber: "LFP8C7PC3R1K12157",
|
||||
vin: "LFP8C7PC3R1K12157",
|
||||
plateTypeId: 9,
|
||||
plateTypeTitle: "پلاک قدیمی",
|
||||
platePartOne: 16,
|
||||
plateSerialNumber: 60,
|
||||
plateLetterid: 12,
|
||||
plateLetterTitle: "م ",
|
||||
vehicleSystemTitle: "فائو ( FAW )",
|
||||
vehicleGroupId: 2,
|
||||
vehicleGroupTitle: "سواری چهار سیلندر",
|
||||
insurerNationalCode: userDetail.nationalCodeOfInsurer,
|
||||
insurerName: "هانيه کارخانهء",
|
||||
ownerNationalCode: userDetail.nationalCodeOfInsurer,
|
||||
previousId: 70006331822,
|
||||
noLossYearsCount: 4,
|
||||
platePartThree: 498,
|
||||
lossDocuments: [],
|
||||
},
|
||||
isSuccess: true,
|
||||
statusCode: 200,
|
||||
message: "عملیات با موفقیت انجام شد",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Bodies returned from `makeSandHubRequest` in mock mode (same shape callers expect from real API).
|
||||
*/
|
||||
@@ -401,30 +451,7 @@ export class SandHubService {
|
||||
this.logger.debug(
|
||||
`[MOCK] getTejaratCarBodyInquiry plate=${JSON.stringify(requestPayload)}`,
|
||||
);
|
||||
raw = {
|
||||
data: {
|
||||
printNumber: "MOCK-BADANE-001",
|
||||
companyId: 34,
|
||||
companyName: "بیمه تجارت نو",
|
||||
beginDate: "1404/06/15",
|
||||
endDate: "1405/06/15",
|
||||
issueDate: "1404/06/13",
|
||||
hasEndorsement: null,
|
||||
motorNumber: "MOCK-ENGINE",
|
||||
chassisNumber: "MOCK-CHASSIS",
|
||||
vin: "MOCK-VIN",
|
||||
vehicleSystemTitle: "سایپا",
|
||||
vehicleGroupTitle: "سواری چهار سیلندر",
|
||||
insurerNationalCode: userDetail.nationalCodeOfInsurer,
|
||||
insurerName: "نام آزمایشی",
|
||||
ownerNationalCode: userDetail.nationalCodeOfInsurer,
|
||||
noLossYearsCount: 0,
|
||||
lossDocuments: [],
|
||||
},
|
||||
isSuccess: true,
|
||||
statusCode: 200,
|
||||
message: "mock-ok",
|
||||
};
|
||||
raw = this.getDefaultMockCarBodyInquiryRaw(userDetail);
|
||||
}
|
||||
|
||||
const mapped = this.mapCarBodyInquiryResponse(raw);
|
||||
|
||||
Reference in New Issue
Block a user