forked from Yara724/api
lookups update per client
This commit is contained in:
@@ -7,6 +7,7 @@ import { ExpertBlameV2Controller } from "./expert-blame.v2.controller";
|
|||||||
import { ExpertBlameService } from "./expert-blame.service";
|
import { ExpertBlameService } from "./expert-blame.service";
|
||||||
import { RequestManagementModule } from "src/request-management/request-management.module";
|
import { RequestManagementModule } from "src/request-management/request-management.module";
|
||||||
import { SmsOrchestrationModule } from "src/sms-orchestration/sms-orchestration.module";
|
import { SmsOrchestrationModule } from "src/sms-orchestration/sms-orchestration.module";
|
||||||
|
import { LookupsModule } from "src/lookups/lookups.module";
|
||||||
import { ClaimRequestManagementModule } from "src/claim-request-management/claim-request-management.module";
|
import { ClaimRequestManagementModule } from "src/claim-request-management/claim-request-management.module";
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
@@ -17,6 +18,7 @@ import { ClaimRequestManagementModule } from "src/claim-request-management/claim
|
|||||||
PlatesModule,
|
PlatesModule,
|
||||||
SmsOrchestrationModule,
|
SmsOrchestrationModule,
|
||||||
ClaimRequestManagementModule,
|
ClaimRequestManagementModule,
|
||||||
|
LookupsModule,
|
||||||
],
|
],
|
||||||
controllers: [ExpertBlameController, ExpertBlameV2Controller],
|
controllers: [ExpertBlameController, ExpertBlameV2Controller],
|
||||||
providers: [ExpertBlameService],
|
providers: [ExpertBlameService],
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import {
|
|||||||
} from "src/helpers/unified-file-status";
|
} from "src/helpers/unified-file-status";
|
||||||
import { applyListQueryV2, isInListDateRange, parseListDateRange } from "src/helpers/list-query-v2";
|
import { applyListQueryV2, isInListDateRange, parseListDateRange } from "src/helpers/list-query-v2";
|
||||||
import { ClaimCaseDbService } from "src/claim-request-management/entites/db-service/claim-case.db.service";
|
import { ClaimCaseDbService } from "src/claim-request-management/entites/db-service/claim-case.db.service";
|
||||||
|
import { LookupsService } from "src/lookups/lookups.service";
|
||||||
import { ListQueryV2Dto } from "src/common/dto/list-query-v2.dto";
|
import { ListQueryV2Dto } from "src/common/dto/list-query-v2.dto";
|
||||||
import {
|
import {
|
||||||
UnifiedFileStatusReportDto,
|
UnifiedFileStatusReportDto,
|
||||||
@@ -126,6 +127,7 @@ export class ExpertBlameService {
|
|||||||
private readonly smsOrchestrationService: SmsOrchestrationService,
|
private readonly smsOrchestrationService: SmsOrchestrationService,
|
||||||
private readonly expertFileActivityDbService: ExpertFileActivityDbService,
|
private readonly expertFileActivityDbService: ExpertFileActivityDbService,
|
||||||
private readonly claimCaseDbService: ClaimCaseDbService,
|
private readonly claimCaseDbService: ClaimCaseDbService,
|
||||||
|
private readonly lookupsService: LookupsService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
private async loadClaimsByPublicIds(
|
private async loadClaimsByPublicIds(
|
||||||
@@ -2424,21 +2426,7 @@ export class ExpertBlameService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getAccidentField() {
|
async getAccidentField() {
|
||||||
try {
|
return await this.lookupsService.getAccidentFields();
|
||||||
const ac_reason = await readFile(
|
|
||||||
"src/static/ACCIDENT_REASON.json",
|
|
||||||
"utf-8",
|
|
||||||
);
|
|
||||||
const ac_type = await readFile("src/static/ACCIDENT_TYPE.json", "utf-8");
|
|
||||||
const ac_way = await readFile("src/static/ACCIDENT_WAY.json", "utf-8");
|
|
||||||
return {
|
|
||||||
accidentReason: JSON.parse(ac_reason),
|
|
||||||
accidentType: JSON.parse(ac_type),
|
|
||||||
accidentWay: JSON.parse(ac_way),
|
|
||||||
};
|
|
||||||
} catch (err) {
|
|
||||||
this.logger.error(err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async inPersonVisit(requestId: string, actorDetail: any) {
|
async inPersonVisit(requestId: string, actorDetail: any) {
|
||||||
|
|||||||
58
src/fanavaran/fanavaran-lookup.config.ts
Normal file
58
src/fanavaran/fanavaran-lookup.config.ts
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import type { FanavaranClientKey } from "src/core/config/fanavaran-client.config";
|
||||||
|
|
||||||
|
export const FANAVARAN_LOOKUP_BASE_URL =
|
||||||
|
"https://apimanager.iraneit.com/BimeApiManager/api/BimeApi/v2.0";
|
||||||
|
|
||||||
|
export interface FanavaranRemoteLookupDefinition {
|
||||||
|
name: string;
|
||||||
|
url: string;
|
||||||
|
cacheFile: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Fanavaran API lookups synced per client (Parsian fetches on first call). */
|
||||||
|
export const FANAVARAN_REMOTE_LOOKUPS: FanavaranRemoteLookupDefinition[] = [
|
||||||
|
{
|
||||||
|
name: "accident-causes",
|
||||||
|
url: `${FANAVARAN_LOOKUP_BASE_URL}/car/base-info/accident-causes`,
|
||||||
|
cacheFile: "accident-causes.json",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "accident-report-type",
|
||||||
|
url: `${FANAVARAN_LOOKUP_BASE_URL}/car/code-list/accident-report-type`,
|
||||||
|
cacheFile: "accident-report-type.json",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "vehicle-use-types",
|
||||||
|
url: `${FANAVARAN_LOOKUP_BASE_URL}/car/base-info/vehicle-use-types`,
|
||||||
|
cacheFile: "vehicle-use-types.json",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "dmg-pay-method",
|
||||||
|
url: `${FANAVARAN_LOOKUP_BASE_URL}/car/code-list/dmg-pay-method`,
|
||||||
|
cacheFile: "dmg-pay-method.json",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "driving-licence-types",
|
||||||
|
url: `${FANAVARAN_LOOKUP_BASE_URL}/car/base-info/driving-licence-types`,
|
||||||
|
cacheFile: "driving-licence-types.json",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "accident-culprit-type",
|
||||||
|
url: `${FANAVARAN_LOOKUP_BASE_URL}/car/code-list/accident-culprit-type`,
|
||||||
|
cacheFile: "accident-culprit-type.json",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const TEJARAT_STATIC_ACCIDENT_FILES = {
|
||||||
|
accidentReason: "ACCIDENT_REASON.json",
|
||||||
|
accidentWay: "ACCIDENT_WAY.json",
|
||||||
|
accidentType: "ACCIDENT_TYPE.json",
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export function fanavaranLookupCacheDir(clientKey: FanavaranClientKey): string {
|
||||||
|
return `${process.cwd()}/files/fanavaran-lookups/${clientKey}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function tejaratStaticAccidentFilePath(fileName: string): string {
|
||||||
|
return `${process.cwd()}/src/static/${fileName}`;
|
||||||
|
}
|
||||||
10
src/fanavaran/fanavaran-lookup.module.ts
Normal file
10
src/fanavaran/fanavaran-lookup.module.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { Module } from "@nestjs/common";
|
||||||
|
import { HttpModule } from "@nestjs/axios";
|
||||||
|
import { FanavaranLookupService } from "./fanavaran-lookup.service";
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [HttpModule],
|
||||||
|
providers: [FanavaranLookupService],
|
||||||
|
exports: [FanavaranLookupService],
|
||||||
|
})
|
||||||
|
export class FanavaranLookupModule {}
|
||||||
241
src/fanavaran/fanavaran-lookup.service.ts
Normal file
241
src/fanavaran/fanavaran-lookup.service.ts
Normal file
@@ -0,0 +1,241 @@
|
|||||||
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
||||||
|
import { join } from "node:path";
|
||||||
|
import { HttpService } from "@nestjs/axios";
|
||||||
|
import {
|
||||||
|
BadGatewayException,
|
||||||
|
Injectable,
|
||||||
|
Logger,
|
||||||
|
NotFoundException,
|
||||||
|
} from "@nestjs/common";
|
||||||
|
import { firstValueFrom } from "rxjs";
|
||||||
|
import { isAxiosError } from "axios";
|
||||||
|
import {
|
||||||
|
getFanavaranClientProfile,
|
||||||
|
type FanavaranClientKey,
|
||||||
|
} from "src/core/config/fanavaran-client.config";
|
||||||
|
import {
|
||||||
|
fanavaranLookupCacheDir,
|
||||||
|
tejaratStaticAccidentFilePath,
|
||||||
|
} from "./fanavaran-lookup.config";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class FanavaranLookupService {
|
||||||
|
private readonly logger = new Logger(FanavaranLookupService.name);
|
||||||
|
|
||||||
|
private readonly getAppTokenUrl =
|
||||||
|
"https://apimanager.iraneit.com/BimeApiManager/api/EITAuthentication/GetAppToken";
|
||||||
|
private readonly loginUrl =
|
||||||
|
"https://apimanager.iraneit.com/BimeApiManager/api/EITAuthentication/Login";
|
||||||
|
|
||||||
|
constructor(private readonly httpService: HttpService) {}
|
||||||
|
|
||||||
|
private cacheFilePath(clientKey: FanavaranClientKey, fileName: string): string {
|
||||||
|
return join(fanavaranLookupCacheDir(clientKey), fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
async readCacheFile<T>(
|
||||||
|
clientKey: FanavaranClientKey,
|
||||||
|
fileName: string,
|
||||||
|
): Promise<T | null> {
|
||||||
|
try {
|
||||||
|
const content = await readFile(
|
||||||
|
this.cacheFilePath(clientKey, fileName),
|
||||||
|
"utf-8",
|
||||||
|
);
|
||||||
|
return JSON.parse(content) as T;
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async writeCacheFile(
|
||||||
|
clientKey: FanavaranClientKey,
|
||||||
|
fileName: string,
|
||||||
|
data: unknown,
|
||||||
|
): Promise<void> {
|
||||||
|
const dir = fanavaranLookupCacheDir(clientKey);
|
||||||
|
await mkdir(dir, { recursive: true });
|
||||||
|
await writeFile(
|
||||||
|
join(dir, fileName),
|
||||||
|
`${JSON.stringify(data, null, 2)}\n`,
|
||||||
|
"utf-8",
|
||||||
|
);
|
||||||
|
this.logger.log(
|
||||||
|
`Cached Fanavaran lookup ${fileName} for client ${clientKey}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async readTejaratStaticAccidentFile<T>(fileName: string): Promise<T> {
|
||||||
|
const cached = await readFile(tejaratStaticAccidentFilePath(fileName), "utf-8");
|
||||||
|
return JSON.parse(cached) as T;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getAppToken(config: {
|
||||||
|
appName: string;
|
||||||
|
secret: string;
|
||||||
|
}): Promise<string> {
|
||||||
|
const response = await firstValueFrom(
|
||||||
|
this.httpService.post(this.getAppTokenUrl, "", {
|
||||||
|
headers: {
|
||||||
|
appname: config.appName,
|
||||||
|
secret: config.secret,
|
||||||
|
"Content-Length": "0",
|
||||||
|
},
|
||||||
|
transformRequest: [
|
||||||
|
(_data, headers) => {
|
||||||
|
if (headers) {
|
||||||
|
delete headers["Content-Type"];
|
||||||
|
delete headers["content-type"];
|
||||||
|
}
|
||||||
|
return _data;
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
const appToken =
|
||||||
|
response.headers.apptoken ||
|
||||||
|
response.headers.appToken ||
|
||||||
|
response.headers["apptoken"] ||
|
||||||
|
response.headers["appToken"];
|
||||||
|
|
||||||
|
if (!appToken) {
|
||||||
|
throw new BadGatewayException("Failed to get Fanavaran appToken");
|
||||||
|
}
|
||||||
|
|
||||||
|
return appToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async login(
|
||||||
|
appToken: string,
|
||||||
|
config: { username: string; password: string },
|
||||||
|
): Promise<string> {
|
||||||
|
const response = await firstValueFrom(
|
||||||
|
this.httpService.post(this.loginUrl, "", {
|
||||||
|
headers: {
|
||||||
|
appToken,
|
||||||
|
userName: config.username,
|
||||||
|
password: config.password,
|
||||||
|
"Content-Length": "0",
|
||||||
|
},
|
||||||
|
transformRequest: [
|
||||||
|
(_data, headers) => {
|
||||||
|
if (headers) {
|
||||||
|
delete headers["Content-Type"];
|
||||||
|
delete headers["content-type"];
|
||||||
|
}
|
||||||
|
return _data;
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
const authenticationToken =
|
||||||
|
response.headers.authenticationtoken ||
|
||||||
|
response.headers.authenticationToken ||
|
||||||
|
response.headers["authenticationtoken"] ||
|
||||||
|
response.headers["authenticationToken"] ||
|
||||||
|
response.data?.authenticationtoken ||
|
||||||
|
response.data?.authenticationToken ||
|
||||||
|
response.data?.authentication_token;
|
||||||
|
|
||||||
|
if (!authenticationToken) {
|
||||||
|
throw new BadGatewayException("Failed to get Fanavaran authenticationToken");
|
||||||
|
}
|
||||||
|
|
||||||
|
return authenticationToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchFromFanavaran(
|
||||||
|
clientKey: FanavaranClientKey,
|
||||||
|
url: string,
|
||||||
|
): Promise<unknown> {
|
||||||
|
const profile = getFanavaranClientProfile(clientKey);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const appToken = await this.getAppToken(profile.auth);
|
||||||
|
const authenticationToken = await this.login(appToken, profile.auth);
|
||||||
|
|
||||||
|
const response = await firstValueFrom(
|
||||||
|
this.httpService.get(url, {
|
||||||
|
headers: {
|
||||||
|
authenticationToken,
|
||||||
|
CorpId: profile.auth.corpId,
|
||||||
|
ContractId: profile.auth.contractId,
|
||||||
|
Location: profile.auth.location,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
timeout: 20000,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
const message = isAxiosError(error)
|
||||||
|
? error.response?.data?.Message ||
|
||||||
|
error.response?.data?.message ||
|
||||||
|
error.message
|
||||||
|
: error instanceof Error
|
||||||
|
? error.message
|
||||||
|
: "Fanavaran lookup request failed";
|
||||||
|
|
||||||
|
this.logger.error(
|
||||||
|
`Fanavaran lookup fetch failed for ${clientKey} (${url}): ${message}`,
|
||||||
|
);
|
||||||
|
throw new BadGatewayException(String(message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getRemoteLookup(
|
||||||
|
clientKey: FanavaranClientKey,
|
||||||
|
url: string,
|
||||||
|
cacheFile: string,
|
||||||
|
fallback?: () => Promise<unknown>,
|
||||||
|
): Promise<unknown> {
|
||||||
|
const cached = await this.readCacheFile(clientKey, cacheFile);
|
||||||
|
if (cached !== null) {
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await this.fetchFromFanavaran(clientKey, url);
|
||||||
|
await this.writeCacheFile(clientKey, cacheFile, data);
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
if (fallback) {
|
||||||
|
this.logger.warn(
|
||||||
|
`Fanavaran lookup fetch failed for ${clientKey}/${cacheFile}; using fallback`,
|
||||||
|
);
|
||||||
|
const data = await fallback();
|
||||||
|
await this.writeCacheFile(clientKey, cacheFile, data);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mapFanavaranAccidentCausesToReasonOptions(
|
||||||
|
causes: unknown,
|
||||||
|
): { id: number; label: string; fanavaran: number }[] {
|
||||||
|
if (!Array.isArray(causes)) {
|
||||||
|
throw new NotFoundException("Fanavaran accident-causes response is invalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
return causes
|
||||||
|
.filter(
|
||||||
|
(item) =>
|
||||||
|
item &&
|
||||||
|
typeof item === "object" &&
|
||||||
|
(item as { IsActive?: number }).IsActive === 1 &&
|
||||||
|
typeof (item as { Id?: unknown }).Id === "number",
|
||||||
|
)
|
||||||
|
.map((item) => {
|
||||||
|
const row = item as { Id: number; Caption?: string };
|
||||||
|
return {
|
||||||
|
id: row.Id,
|
||||||
|
label: row.Caption ?? String(row.Id),
|
||||||
|
fanavaran: row.Id,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -163,6 +163,7 @@ export class LookupsController {
|
|||||||
schema: {
|
schema: {
|
||||||
type: "object",
|
type: "object",
|
||||||
properties: {
|
properties: {
|
||||||
|
client: { type: "string", example: "tejaratno" },
|
||||||
accidentWay: {
|
accidentWay: {
|
||||||
type: "array",
|
type: "array",
|
||||||
items: {
|
items: {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Module } from "@nestjs/common";
|
import { Module } from "@nestjs/common";
|
||||||
import { MongooseModule } from "@nestjs/mongoose";
|
import { MongooseModule } from "@nestjs/mongoose";
|
||||||
|
import { FanavaranLookupModule } from "src/fanavaran/fanavaran-lookup.module";
|
||||||
import { LookupDbService } from "./entities/db-service/lookup.db.service";
|
import { LookupDbService } from "./entities/db-service/lookup.db.service";
|
||||||
import { LookupModel, LookupSchema } from "./entities/schema/lookup.schema";
|
import { LookupModel, LookupSchema } from "./entities/schema/lookup.schema";
|
||||||
import { LookupsController } from "./lookups.controller";
|
import { LookupsController } from "./lookups.controller";
|
||||||
@@ -7,6 +8,7 @@ import { LookupsService } from "./lookups.service";
|
|||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
|
FanavaranLookupModule,
|
||||||
MongooseModule.forFeature([
|
MongooseModule.forFeature([
|
||||||
{ name: LookupModel.name, schema: LookupSchema },
|
{ name: LookupModel.name, schema: LookupSchema },
|
||||||
]),
|
]),
|
||||||
|
|||||||
@@ -1,15 +1,47 @@
|
|||||||
import { readFile } from "node:fs/promises";
|
|
||||||
import { Injectable, Logger, NotFoundException } from "@nestjs/common";
|
import { Injectable, Logger, NotFoundException } from "@nestjs/common";
|
||||||
|
import { resolveFanavaranClientKey } from "src/core/config/fanavaran-client.config";
|
||||||
|
import {
|
||||||
|
FANAVARAN_REMOTE_LOOKUPS,
|
||||||
|
TEJARAT_STATIC_ACCIDENT_FILES,
|
||||||
|
} from "src/fanavaran/fanavaran-lookup.config";
|
||||||
|
import { FanavaranLookupService } from "src/fanavaran/fanavaran-lookup.service";
|
||||||
import { LookupDbService } from "./entities/db-service/lookup.db.service";
|
import { LookupDbService } from "./entities/db-service/lookup.db.service";
|
||||||
|
|
||||||
|
type TejaratAccidentReasonRow = {
|
||||||
|
id: number;
|
||||||
|
persianLabel: string;
|
||||||
|
fanavaranID: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type TejaratAccidentLabelRow = {
|
||||||
|
id: number;
|
||||||
|
persianLabel: string;
|
||||||
|
};
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LookupsService {
|
export class LookupsService {
|
||||||
private readonly logger = new Logger(LookupsService.name);
|
private readonly logger = new Logger(LookupsService.name);
|
||||||
|
|
||||||
constructor(private readonly lookupDbService: LookupDbService) {}
|
constructor(
|
||||||
|
private readonly lookupDbService: LookupDbService,
|
||||||
|
private readonly fanavaranLookupService: FanavaranLookupService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
private activeClientKey() {
|
||||||
|
return resolveFanavaranClientKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
private findRemoteLookup(name: string) {
|
||||||
|
const lookup = FANAVARAN_REMOTE_LOOKUPS.find((item) => item.name === name);
|
||||||
|
if (!lookup) {
|
||||||
|
throw new Error(`Unknown Fanavaran remote lookup: ${name}`);
|
||||||
|
}
|
||||||
|
return lookup;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns stored `response` for a lookup document by `name` in the lookups collection.
|
* Returns stored `response` for a lookup document by `name` in the lookups collection.
|
||||||
|
* Legacy Tejarat seed data — used as fallback when live fetch is unavailable.
|
||||||
*/
|
*/
|
||||||
async getLookup(lookupName: string): Promise<any> {
|
async getLookup(lookupName: string): Promise<any> {
|
||||||
const doc = await this.lookupDbService.findOne({ name: lookupName });
|
const doc = await this.lookupDbService.findOne({ name: lookupName });
|
||||||
@@ -20,42 +52,114 @@ export class LookupsService {
|
|||||||
return doc.response;
|
return doc.response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async getClientRemoteLookup(lookupName: string): Promise<unknown> {
|
||||||
|
const clientKey = this.activeClientKey();
|
||||||
|
const definition = this.findRemoteLookup(lookupName);
|
||||||
|
|
||||||
|
return this.fanavaranLookupService.getRemoteLookup(
|
||||||
|
clientKey,
|
||||||
|
definition.url,
|
||||||
|
definition.cacheFile,
|
||||||
|
clientKey === "tejaratno"
|
||||||
|
? async () => this.getLookup(lookupName)
|
||||||
|
: undefined,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
async getAccidentCauses(): Promise<any> {
|
async getAccidentCauses(): Promise<any> {
|
||||||
return await this.getLookup("accident-causes");
|
return await this.getClientRemoteLookup("accident-causes");
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAccidentReportType(): Promise<any> {
|
async getAccidentReportType(): Promise<any> {
|
||||||
return await this.getLookup("accident-report-type");
|
return await this.getClientRemoteLookup("accident-report-type");
|
||||||
}
|
}
|
||||||
|
|
||||||
async getVehicleUseTypes(): Promise<any> {
|
async getVehicleUseTypes(): Promise<any> {
|
||||||
return await this.getLookup("vehicle-use-types");
|
return await this.getClientRemoteLookup("vehicle-use-types");
|
||||||
}
|
}
|
||||||
|
|
||||||
async getDmgPayMethod(): Promise<any> {
|
async getDmgPayMethod(): Promise<any> {
|
||||||
return await this.getLookup("dmg-pay-method");
|
return await this.getClientRemoteLookup("dmg-pay-method");
|
||||||
}
|
}
|
||||||
|
|
||||||
async getDrivingLicenceTypes(): Promise<any> {
|
async getDrivingLicenceTypes(): Promise<any> {
|
||||||
return await this.getLookup("driving-licence-types");
|
return await this.getClientRemoteLookup("driving-licence-types");
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAccidentCulpritType(): Promise<any> {
|
async getAccidentCulpritType(): Promise<any> {
|
||||||
return await this.getLookup("accident-culprit-type");
|
return await this.getClientRemoteLookup("accident-culprit-type");
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAccidentWay(): Promise<{ id: number; label: string }[]> {
|
async getAccidentWay(): Promise<{ id: number; label: string }[]> {
|
||||||
const raw: { id: number; persianLabel: string }[] = JSON.parse(
|
const clientKey = this.activeClientKey();
|
||||||
await readFile("src/static/ACCIDENT_WAY.json", "utf-8"),
|
const fileName = TEJARAT_STATIC_ACCIDENT_FILES.accidentWay;
|
||||||
|
|
||||||
|
const cached = await this.fanavaranLookupService.readCacheFile<
|
||||||
|
TejaratAccidentLabelRow[]
|
||||||
|
>(clientKey, fileName);
|
||||||
|
const raw =
|
||||||
|
cached ??
|
||||||
|
(clientKey === "tejaratno"
|
||||||
|
? await this.fanavaranLookupService.readTejaratStaticAccidentFile<
|
||||||
|
TejaratAccidentLabelRow[]
|
||||||
|
>(fileName)
|
||||||
|
: null);
|
||||||
|
|
||||||
|
if (!raw) {
|
||||||
|
this.logger.warn(
|
||||||
|
`No accident-way lookup for client ${clientKey}; falling back to tejarat static file`,
|
||||||
);
|
);
|
||||||
|
const fallback =
|
||||||
|
await this.fanavaranLookupService.readTejaratStaticAccidentFile<
|
||||||
|
TejaratAccidentLabelRow[]
|
||||||
|
>(fileName);
|
||||||
|
return fallback.map((item) => ({
|
||||||
|
id: item.id,
|
||||||
|
label: item.persianLabel,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
return raw.map((item) => ({ id: item.id, label: item.persianLabel }));
|
return raw.map((item) => ({ id: item.id, label: item.persianLabel }));
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAccidentReason(): Promise<
|
async getAccidentReason(): Promise<
|
||||||
{ id: number; label: string; fanavaran: number }[]
|
{ id: number; label: string; fanavaran: number }[]
|
||||||
> {
|
> {
|
||||||
const raw: { id: number; persianLabel: string; fanavaranID: number }[] =
|
const clientKey = this.activeClientKey();
|
||||||
JSON.parse(await readFile("src/static/ACCIDENT_REASON.json", "utf-8"));
|
|
||||||
|
if (clientKey === "parsian") {
|
||||||
|
const cacheFile = "accident-reason-options.json";
|
||||||
|
const cached =
|
||||||
|
await this.fanavaranLookupService.readCacheFile<
|
||||||
|
{ id: number; label: string; fanavaran: number }[]
|
||||||
|
>(clientKey, cacheFile);
|
||||||
|
if (cached) {
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
|
|
||||||
|
const causes = await this.getAccidentCauses();
|
||||||
|
const mapped =
|
||||||
|
this.fanavaranLookupService.mapFanavaranAccidentCausesToReasonOptions(
|
||||||
|
causes,
|
||||||
|
);
|
||||||
|
await this.fanavaranLookupService.writeCacheFile(
|
||||||
|
clientKey,
|
||||||
|
cacheFile,
|
||||||
|
mapped,
|
||||||
|
);
|
||||||
|
return mapped;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileName = TEJARAT_STATIC_ACCIDENT_FILES.accidentReason;
|
||||||
|
const cached = await this.fanavaranLookupService.readCacheFile<
|
||||||
|
TejaratAccidentReasonRow[]
|
||||||
|
>(clientKey, fileName);
|
||||||
|
const raw =
|
||||||
|
cached ??
|
||||||
|
(await this.fanavaranLookupService.readTejaratStaticAccidentFile<
|
||||||
|
TejaratAccidentReasonRow[]
|
||||||
|
>(fileName));
|
||||||
|
|
||||||
return raw.map((item) => ({
|
return raw.map((item) => ({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
label: item.persianLabel,
|
label: item.persianLabel,
|
||||||
@@ -64,9 +168,34 @@ export class LookupsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getAccidentType(): Promise<{ id: number; label: string }[]> {
|
async getAccidentType(): Promise<{ id: number; label: string }[]> {
|
||||||
const raw: { id: number; persianLabel: string }[] = JSON.parse(
|
const clientKey = this.activeClientKey();
|
||||||
await readFile("src/static/ACCIDENT_TYPE.json", "utf-8"),
|
const fileName = TEJARAT_STATIC_ACCIDENT_FILES.accidentType;
|
||||||
|
|
||||||
|
const cached = await this.fanavaranLookupService.readCacheFile<
|
||||||
|
TejaratAccidentLabelRow[]
|
||||||
|
>(clientKey, fileName);
|
||||||
|
const raw =
|
||||||
|
cached ??
|
||||||
|
(clientKey === "tejaratno"
|
||||||
|
? await this.fanavaranLookupService.readTejaratStaticAccidentFile<
|
||||||
|
TejaratAccidentLabelRow[]
|
||||||
|
>(fileName)
|
||||||
|
: null);
|
||||||
|
|
||||||
|
if (!raw) {
|
||||||
|
this.logger.warn(
|
||||||
|
`No accident-type lookup for client ${clientKey}; falling back to tejarat static file`,
|
||||||
);
|
);
|
||||||
|
const fallback =
|
||||||
|
await this.fanavaranLookupService.readTejaratStaticAccidentFile<
|
||||||
|
TejaratAccidentLabelRow[]
|
||||||
|
>(fileName);
|
||||||
|
return fallback.map((item) => ({
|
||||||
|
id: item.id,
|
||||||
|
label: item.persianLabel,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
return raw.map((item) => ({ id: item.id, label: item.persianLabel }));
|
return raw.map((item) => ({ id: item.id, label: item.persianLabel }));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,12 +203,18 @@ export class LookupsService {
|
|||||||
accidentWay: { id: number; label: string }[];
|
accidentWay: { id: number; label: string }[];
|
||||||
accidentReason: { id: number; label: string; fanavaran: number }[];
|
accidentReason: { id: number; label: string; fanavaran: number }[];
|
||||||
accidentType: { id: number; label: string }[];
|
accidentType: { id: number; label: string }[];
|
||||||
|
client: string;
|
||||||
}> {
|
}> {
|
||||||
const [accidentWay, accidentReason, accidentType] = await Promise.all([
|
const [accidentWay, accidentReason, accidentType] = await Promise.all([
|
||||||
this.getAccidentWay(),
|
this.getAccidentWay(),
|
||||||
this.getAccidentReason(),
|
this.getAccidentReason(),
|
||||||
this.getAccidentType(),
|
this.getAccidentType(),
|
||||||
]);
|
]);
|
||||||
return { accidentWay, accidentReason, accidentType };
|
return {
|
||||||
|
client: this.activeClientKey(),
|
||||||
|
accidentWay,
|
||||||
|
accidentReason,
|
||||||
|
accidentType,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user