forked from Shared/esg
final update on moallm client
This commit is contained in:
72
src/common/helpers/centinsur-response.helper.ts
Normal file
72
src/common/helpers/centinsur-response.helper.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import { InquiryType } from '../enums/inquiry-type.enum';
|
||||
|
||||
export interface CentInsurApiResponse {
|
||||
IsSucceed?: boolean;
|
||||
Result?: {
|
||||
Result?: boolean;
|
||||
ErrorMessage?: string | null;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
TrackingCode?: string;
|
||||
message?: string;
|
||||
code?: string;
|
||||
success?: boolean;
|
||||
}
|
||||
|
||||
export interface CentInsurProviderError {
|
||||
message: string;
|
||||
code: string;
|
||||
providerTrackingCode?: string;
|
||||
}
|
||||
|
||||
function getNoMatchMessage(inquiryType?: InquiryType): string {
|
||||
switch (inquiryType) {
|
||||
case InquiryType.REAL_ESTATE:
|
||||
return 'No property ownership found for the provided national code and postal code';
|
||||
default:
|
||||
return 'Inquiry returned no matching result';
|
||||
}
|
||||
}
|
||||
|
||||
export function getCentInsurProviderError(
|
||||
body: CentInsurApiResponse,
|
||||
inquiryType?: InquiryType,
|
||||
): CentInsurProviderError | null {
|
||||
if (!('IsSucceed' in body)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const providerTrackingCode = body.TrackingCode?.trim() || undefined;
|
||||
|
||||
if (body.IsSucceed === false) {
|
||||
return {
|
||||
message: body.Result?.ErrorMessage?.trim() || 'Request failed',
|
||||
code: 'API_ERROR',
|
||||
providerTrackingCode,
|
||||
};
|
||||
}
|
||||
|
||||
if (body.Result?.Result === false) {
|
||||
return {
|
||||
message: body.Result?.ErrorMessage?.trim() || getNoMatchMessage(inquiryType),
|
||||
code: 'INQUIRY_NO_MATCH',
|
||||
providerTrackingCode,
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function describeCentInsurResponse(body: CentInsurApiResponse): string {
|
||||
const innerResult =
|
||||
body.Result && 'Result' in body.Result ? String(body.Result.Result) : 'undefined';
|
||||
|
||||
return [
|
||||
`IsSucceed=${String(body.IsSucceed)}`,
|
||||
`Result.Result=${innerResult}`,
|
||||
`ErrorMessage=${body.Result?.ErrorMessage ?? 'none'}`,
|
||||
body.TrackingCode ? `TrackingCode=${body.TrackingCode}` : null,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(' | ');
|
||||
}
|
||||
32
src/common/helpers/inquiry-response.helper.ts
Normal file
32
src/common/helpers/inquiry-response.helper.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { BaseInquiryResponseDto } from '../dto/base-inquiry-response.dto';
|
||||
import { NormalizedErrorDto } from '../dto/normalized-error.dto';
|
||||
|
||||
export function buildInquiryResponse<T = Record<string, unknown>>(params: {
|
||||
success: boolean;
|
||||
provider: string;
|
||||
trackingCode: string;
|
||||
message: string;
|
||||
duration: number;
|
||||
data?: T | null;
|
||||
error?: NormalizedErrorDto | null;
|
||||
}): BaseInquiryResponseDto<T> {
|
||||
return {
|
||||
success: params.success,
|
||||
provider: params.provider,
|
||||
trackingCode: params.trackingCode,
|
||||
message: params.message,
|
||||
duration: params.duration,
|
||||
data: params.success ? (params.data ?? null) : null,
|
||||
error: params.success ? null : (params.error ?? null),
|
||||
};
|
||||
}
|
||||
|
||||
export function normalizeInquiryResponse<T = Record<string, unknown>>(
|
||||
response: BaseInquiryResponseDto<T>,
|
||||
): BaseInquiryResponseDto<T> {
|
||||
return {
|
||||
...response,
|
||||
data: response.success ? (response.data ?? null) : null,
|
||||
error: response.success ? null : (response.error ?? null),
|
||||
};
|
||||
}
|
||||
124
src/common/helpers/shahkar-response.helper.ts
Normal file
124
src/common/helpers/shahkar-response.helper.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
function decodeXml(value: string): string {
|
||||
return value
|
||||
.replace(/'/g, "'")
|
||||
.replace(/"/g, '"')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/</g, '<')
|
||||
.replace(/&/g, '&');
|
||||
}
|
||||
|
||||
function normalizeSoapTextValue(value: string): string {
|
||||
if (/i:nil\s*=\s*["']true["']/i.test(value)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const nestedStrings = [
|
||||
...value.matchAll(/<(?:[\w]+:)?string[^>]*>([\s\S]*?)<\/(?:[\w]+:)?string>/gi),
|
||||
]
|
||||
.map((match) => decodeXml(match[1].trim()))
|
||||
.filter(Boolean);
|
||||
|
||||
if (nestedStrings.length > 0) {
|
||||
return nestedStrings.join(', ');
|
||||
}
|
||||
|
||||
return decodeXml(value.trim());
|
||||
}
|
||||
|
||||
export interface ShahkarInquiryFields {
|
||||
response?: string;
|
||||
result?: string;
|
||||
comment?: string;
|
||||
requestId?: string;
|
||||
id?: string;
|
||||
ErrorNams?: string;
|
||||
}
|
||||
|
||||
export function parseShahkarInqueryResult(soapXml: string): ShahkarInquiryFields {
|
||||
const blockMatch = soapXml.match(
|
||||
/<(?:[\w]+:)?ShahkarInqueryResult[^>]*>([\s\S]*?)<\/(?:[\w]+:)?ShahkarInqueryResult>/i,
|
||||
);
|
||||
|
||||
if (!blockMatch) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const fields: Record<string, string> = {};
|
||||
const tagRegex = /<(?:[\w]+:)?(\w+)(?:[^>]*)>([\s\S]*?)<\/(?:[\w]+:)?\1>/gi;
|
||||
let match: RegExpExecArray | null;
|
||||
|
||||
while ((match = tagRegex.exec(blockMatch[1])) !== null) {
|
||||
fields[match[1]] = normalizeSoapTextValue(match[2]);
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
export function normalizeShahkarFields(raw: Record<string, unknown>): ShahkarInquiryFields {
|
||||
const readString = (value: unknown): string | undefined => {
|
||||
if (value === null || value === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
const text = String(value).trim();
|
||||
return text.length > 0 ? text : undefined;
|
||||
};
|
||||
|
||||
return {
|
||||
response: readString(raw.response ?? raw.Response),
|
||||
result: readString(raw.result ?? raw.Result),
|
||||
comment: readString(raw.comment ?? raw.Comment),
|
||||
requestId: readString(raw.requestId ?? raw.RequestId),
|
||||
id: readString(raw.id ?? raw.Id),
|
||||
ErrorNams: readString(raw.ErrorNams ?? raw.errorNams),
|
||||
};
|
||||
}
|
||||
|
||||
export function isShahkarSuccess(fields: ShahkarInquiryFields): boolean {
|
||||
const responseCode = fields.response?.trim();
|
||||
const resultText = fields.result?.trim().toUpperCase() ?? '';
|
||||
|
||||
return responseCode === '200' && resultText.startsWith('OK');
|
||||
}
|
||||
|
||||
export function getShahkarProviderError(
|
||||
fields: ShahkarInquiryFields,
|
||||
): { message: string; code: string; providerCode?: string; providerTrackingCode?: string } | null {
|
||||
if (isShahkarSuccess(fields)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const comment = fields.comment?.trim();
|
||||
const errorNams = fields.ErrorNams?.trim();
|
||||
const resultText = fields.result?.trim();
|
||||
const responseCode = fields.response?.trim();
|
||||
const providerTrackingCode = fields.requestId?.trim() || undefined;
|
||||
|
||||
if (resultText === 'NotIdentifiedException' || responseCode === '600') {
|
||||
return {
|
||||
message:
|
||||
comment ||
|
||||
'No match found between the provided national code and mobile number',
|
||||
code: 'INQUIRY_NO_MATCH',
|
||||
providerCode: resultText ?? responseCode,
|
||||
providerTrackingCode,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
message: comment || errorNams || resultText || 'Shahkar inquiry failed',
|
||||
code: 'PROVIDER_ERROR',
|
||||
providerCode: resultText ?? responseCode,
|
||||
providerTrackingCode,
|
||||
};
|
||||
}
|
||||
|
||||
export function describeShahkarResponse(fields: ShahkarInquiryFields): string {
|
||||
return [
|
||||
fields.response ? `response=${fields.response}` : null,
|
||||
fields.result ? `result=${fields.result}` : null,
|
||||
fields.comment ? `comment=${fields.comment}` : null,
|
||||
fields.requestId ? `requestId=${fields.requestId}` : null,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(' | ');
|
||||
}
|
||||
Reference in New Issue
Block a user