forked from Yara724/api
254 lines
7.5 KiB
TypeScript
254 lines
7.5 KiB
TypeScript
import { Injectable, Logger, NotFoundException } from "@nestjs/common";
|
|
import { resolveFanavaranClientKey } from "src/core/config/fanavaran-client.config";
|
|
import {
|
|
FANAVARAN_REMOTE_LOOKUPS,
|
|
type FanavaranRemoteLookupDefinition,
|
|
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";
|
|
|
|
type TejaratAccidentReasonRow = {
|
|
id: number;
|
|
persianLabel: string;
|
|
fanavaranID: number;
|
|
};
|
|
|
|
type TejaratAccidentLabelRow = {
|
|
id: number;
|
|
persianLabel: string;
|
|
};
|
|
|
|
@Injectable()
|
|
export class LookupsService {
|
|
private readonly logger = new Logger(LookupsService.name);
|
|
|
|
constructor(
|
|
private readonly lookupDbService: LookupDbService,
|
|
private readonly fanavaranLookupService: FanavaranLookupService,
|
|
) {}
|
|
|
|
private activeClientKey() {
|
|
return resolveFanavaranClientKey();
|
|
}
|
|
|
|
listFanavaranRemoteLookups(): FanavaranRemoteLookupDefinition[] {
|
|
return FANAVARAN_REMOTE_LOOKUPS;
|
|
}
|
|
|
|
private findRemoteLookup(name: string) {
|
|
const lookup = FANAVARAN_REMOTE_LOOKUPS.find((item) => item.name === name);
|
|
if (!lookup) {
|
|
throw new NotFoundException(`Unknown Fanavaran remote lookup: ${name}`);
|
|
}
|
|
return lookup;
|
|
}
|
|
|
|
/**
|
|
* 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> {
|
|
const doc = await this.lookupDbService.findOne({ name: lookupName });
|
|
if (!doc) {
|
|
this.logger.warn(`Lookup not found in database: ${lookupName}`);
|
|
throw new NotFoundException(`Lookup "${lookupName}" not found`);
|
|
}
|
|
return doc.response;
|
|
}
|
|
|
|
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> {
|
|
return await this.getClientRemoteLookup("accident-causes");
|
|
}
|
|
|
|
async getAccidentReportType(): Promise<any> {
|
|
return await this.getClientRemoteLookup("accident-report-type");
|
|
}
|
|
|
|
async getVehicleUseTypes(): Promise<any> {
|
|
return await this.getClientRemoteLookup("vehicle-use-types");
|
|
}
|
|
|
|
async getDmgPayMethod(): Promise<any> {
|
|
return await this.getClientRemoteLookup("dmg-pay-method");
|
|
}
|
|
|
|
async getDrivingLicenceTypes(): Promise<any> {
|
|
return await this.getClientRemoteLookup("driving-licence-types");
|
|
}
|
|
|
|
async getAccidentCulpritType(): Promise<any> {
|
|
return await this.getClientRemoteLookup("accident-culprit-type");
|
|
}
|
|
|
|
async getInspectionPlace(): Promise<any> {
|
|
return await this.getClientRemoteLookup("inspection-place");
|
|
}
|
|
|
|
async getDropAmountStatus(): Promise<any> {
|
|
return await this.getClientRemoteLookup("drop-amount-status");
|
|
}
|
|
|
|
async getCarComponents(): Promise<any> {
|
|
return await this.getClientRemoteLookup("car-components");
|
|
}
|
|
|
|
async getAccidentLevel(): Promise<any> {
|
|
return await this.getClientRemoteLookup("accident-level");
|
|
}
|
|
|
|
async getExpertStatus(): Promise<any> {
|
|
return await this.getClientRemoteLookup("expert-status");
|
|
}
|
|
|
|
async getVehicleKinds(): Promise<any> {
|
|
return await this.getClientRemoteLookup("vehicle-kinds");
|
|
}
|
|
|
|
async inquiryByVin(vin: string): Promise<unknown> {
|
|
const clientKey = this.activeClientKey();
|
|
return this.fanavaranLookupService.inquiryByVin(clientKey, vin);
|
|
}
|
|
|
|
async getAccidentWay(): Promise<{ id: number; label: string }[]> {
|
|
const clientKey = this.activeClientKey();
|
|
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 }));
|
|
}
|
|
|
|
async getAccidentReason(): Promise<
|
|
{ id: number; label: string; fanavaran: number }[]
|
|
> {
|
|
const clientKey = this.activeClientKey();
|
|
|
|
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) => ({
|
|
id: item.id,
|
|
label: item.persianLabel,
|
|
fanavaran: item.fanavaranID,
|
|
}));
|
|
}
|
|
|
|
async getAccidentType(): Promise<{ id: number; label: string }[]> {
|
|
const clientKey = this.activeClientKey();
|
|
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 }));
|
|
}
|
|
|
|
async getAccidentFields(): Promise<{
|
|
accidentWay: { id: number; label: string }[];
|
|
accidentReason: { id: number; label: string; fanavaran: number }[];
|
|
accidentType: { id: number; label: string }[];
|
|
client: string;
|
|
}> {
|
|
const [accidentWay, accidentReason, accidentType] = await Promise.all([
|
|
this.getAccidentWay(),
|
|
this.getAccidentReason(),
|
|
this.getAccidentType(),
|
|
]);
|
|
return {
|
|
client: this.activeClientKey(),
|
|
accidentWay,
|
|
accidentReason,
|
|
accidentType,
|
|
};
|
|
}
|
|
}
|