mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 23:28:11 +00:00
114 lines
3.7 KiB
TypeScript
114 lines
3.7 KiB
TypeScript
import { Injectable, BadRequestException } from "@nestjs/common";
|
|
import { HttpService } from "@nestjs/axios";
|
|
import { Agent } from "https";
|
|
import { firstValueFrom } from "rxjs";
|
|
import {
|
|
ETradeCompanyInfo,
|
|
ETradeBusinessInfo,
|
|
CompanyRegistrationData,
|
|
} from "@edr/types";
|
|
|
|
@Injectable()
|
|
export class ETradeService {
|
|
private readonly baseUrl = "https://etrade.gov.et/api";
|
|
private readonly referer = "https://etrade.gov.et/business-license-checker";
|
|
|
|
/**
|
|
* The eTrade server serves an incomplete TLS chain (it omits the intermediate
|
|
* CA cert), so Node rejects the handshake with UNABLE_TO_GET_ISSUER_CERT.
|
|
* Scope a relaxed agent to these outbound calls only — the rest of the app
|
|
* keeps full certificate verification.
|
|
*/
|
|
private readonly httpsAgent = new Agent({ rejectUnauthorized: false });
|
|
|
|
constructor(private readonly httpService: HttpService) {}
|
|
|
|
async getCompanyInfoByTin(tin: string): Promise<ETradeCompanyInfo> {
|
|
const url = `${this.baseUrl}/Registration/GetRegistrationInfoByTin/${tin}/en`;
|
|
try {
|
|
const response = await firstValueFrom(
|
|
this.httpService.get<ETradeCompanyInfo>(url, {
|
|
headers: { Referer: this.referer },
|
|
httpsAgent: this.httpsAgent,
|
|
}),
|
|
);
|
|
return response.data;
|
|
} catch (error: any) {
|
|
throw new BadRequestException(
|
|
`Failed to fetch company info from eTrade: ${error.message}`,
|
|
);
|
|
}
|
|
}
|
|
|
|
async getBusinessByLicenseNo(
|
|
licenseNo: string,
|
|
tin: string,
|
|
): Promise<ETradeBusinessInfo> {
|
|
const url = `${this.baseUrl}/BusinessMain/GetBusinessByLicenseNo`;
|
|
try {
|
|
const response = await firstValueFrom(
|
|
this.httpService.get<ETradeBusinessInfo>(url, {
|
|
params: {
|
|
LicenseNo: licenseNo,
|
|
Tin: tin,
|
|
Lang: "en",
|
|
},
|
|
headers: { Referer: this.referer },
|
|
httpsAgent: this.httpsAgent,
|
|
}),
|
|
);
|
|
return response.data;
|
|
} catch (error: any) {
|
|
throw new BadRequestException(
|
|
`Failed to fetch business info from eTrade: ${error.message}`,
|
|
);
|
|
}
|
|
}
|
|
|
|
async resolveCompanyData(tin: string): Promise<{
|
|
companyInfo: ETradeCompanyInfo;
|
|
businessInfo: ETradeBusinessInfo | null;
|
|
}> {
|
|
const companyInfo = await this.getCompanyInfoByTin(tin);
|
|
|
|
if (!companyInfo.Businesses || companyInfo.Businesses.length === 0) {
|
|
return { companyInfo, businessInfo: null };
|
|
}
|
|
|
|
const latestBusiness = companyInfo.Businesses[0];
|
|
try {
|
|
const businessInfo = await this.getBusinessByLicenseNo(
|
|
latestBusiness.LicenceNumber,
|
|
tin,
|
|
);
|
|
return { companyInfo, businessInfo };
|
|
} catch {
|
|
return { companyInfo, businessInfo: null };
|
|
}
|
|
}
|
|
|
|
extractRegistrationData(
|
|
businessInfo: ETradeBusinessInfo,
|
|
): CompanyRegistrationData {
|
|
const primaryManager = businessInfo.AssociateShortInfos?.[0];
|
|
|
|
return {
|
|
licenceNumber: businessInfo.LicenceNumber,
|
|
statusDescription: businessInfo.StatusDescription,
|
|
dateRegistered: businessInfo.DateRegistered,
|
|
renewedFrom: businessInfo.RenewedFrom,
|
|
renewalDate: businessInfo.RenewalDate,
|
|
renewedTo: businessInfo.RenewedTo,
|
|
region: businessInfo.AddressInfo?.Region || "",
|
|
zone: businessInfo.AddressInfo?.Zone || "",
|
|
woreda: businessInfo.AddressInfo?.Woreda || "",
|
|
kebele: businessInfo.AddressInfo?.Kebele || "",
|
|
houseNo: businessInfo.AddressInfo?.HouseNo || "",
|
|
mobilePhone: businessInfo.AddressInfo?.MobilePhone || "",
|
|
regularPhone: businessInfo.AddressInfo?.RegularPhone || "",
|
|
managerName: primaryManager?.ManagerNameEng || "",
|
|
managerPhone: primaryManager?.RegularPhone || "",
|
|
};
|
|
}
|
|
}
|