mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-11-26 00:24:54 +00:00
feat: finish working on mocking inquire application api
This commit is contained in:
@ -12,6 +12,7 @@ import { AllowanceModule } from './allowance/allowance.module';
|
|||||||
import { AuthModule } from './auth/auth.module';
|
import { AuthModule } from './auth/auth.module';
|
||||||
import { CacheModule } from './common/modules/cache/cache.module';
|
import { CacheModule } from './common/modules/cache/cache.module';
|
||||||
import { LookupModule } from './common/modules/lookup/lookup.module';
|
import { LookupModule } from './common/modules/lookup/lookup.module';
|
||||||
|
import { NeoLeapModule } from './common/modules/neoleap/neoleap.module';
|
||||||
import { NotificationModule } from './common/modules/notification/notification.module';
|
import { NotificationModule } from './common/modules/notification/notification.module';
|
||||||
import { OtpModule } from './common/modules/otp/otp.module';
|
import { OtpModule } from './common/modules/otp/otp.module';
|
||||||
import { AllExceptionsFilter, buildI18nValidationExceptionFilter } from './core/filters';
|
import { AllExceptionsFilter, buildI18nValidationExceptionFilter } from './core/filters';
|
||||||
@ -80,6 +81,7 @@ import { UserModule } from './user/user.module';
|
|||||||
UserModule,
|
UserModule,
|
||||||
|
|
||||||
CronModule,
|
CronModule,
|
||||||
|
NeoLeapModule,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
// Global Pipes
|
// Global Pipes
|
||||||
|
|||||||
1
src/common/modules/neoleap/__mocks__/index.ts
Normal file
1
src/common/modules/neoleap/__mocks__/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './inquire-application.mock';
|
||||||
@ -0,0 +1,91 @@
|
|||||||
|
export const INQUIRE_APPLICATION_MOCK = {
|
||||||
|
ResponseHeader: {
|
||||||
|
Version: '1.0.0',
|
||||||
|
MsgUid: 'stringstringstringstringstringstring',
|
||||||
|
Source: 'string',
|
||||||
|
ServiceId: 'string',
|
||||||
|
ReqDateTime: '2025-05-26T10:23:13.812Z',
|
||||||
|
RspDateTime: '2025-05-26T10:23:13.812Z',
|
||||||
|
ResponseCode: 'string',
|
||||||
|
ResponseType: 'Validation Error',
|
||||||
|
ProcessingTime: 0,
|
||||||
|
EncryptionKey: 'string',
|
||||||
|
ResponseDescription: 'string',
|
||||||
|
LocalizedResponseDescription: {
|
||||||
|
Locale: 'string',
|
||||||
|
LocalizedDescription: 'string',
|
||||||
|
},
|
||||||
|
CustomerSpecificResponseDescriptionList: [
|
||||||
|
{
|
||||||
|
Locale: 'string',
|
||||||
|
ResponseDescription: 'string',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
HeaderUserDataList: [
|
||||||
|
{
|
||||||
|
Tag: 'string',
|
||||||
|
Value: 'string',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
InquireApplicationResponseDetails: {
|
||||||
|
InstitutionCode: 'stri',
|
||||||
|
ApplicationTypeDetails: {
|
||||||
|
TypeCode: 'st',
|
||||||
|
Description: 'string',
|
||||||
|
Additional: true,
|
||||||
|
Corporate: true,
|
||||||
|
UserData: 'string',
|
||||||
|
},
|
||||||
|
ApplicationDetails: {
|
||||||
|
ApplicationNumber: 'string',
|
||||||
|
ExternalApplicationNumber: 'string',
|
||||||
|
ApplicationStatus: 'st',
|
||||||
|
Organization: 0,
|
||||||
|
Product: 'stri',
|
||||||
|
ApplicatonDate: '2025-05-26',
|
||||||
|
ApplicationSource: 's',
|
||||||
|
SalesSource: 'string',
|
||||||
|
DeliveryMethod: 's',
|
||||||
|
ProgramCode: 'string',
|
||||||
|
Campaign: 'string',
|
||||||
|
Plastic: 'string',
|
||||||
|
Design: 'string',
|
||||||
|
ProcessStage: 'st',
|
||||||
|
ProcessStageStatus: 's',
|
||||||
|
Score: 'string',
|
||||||
|
ExternalScore: 'string',
|
||||||
|
RequestedLimit: 0,
|
||||||
|
SuggestedLimit: 0,
|
||||||
|
AssignedLimit: 0,
|
||||||
|
AllowedLimitList: [
|
||||||
|
{
|
||||||
|
CreditLimit: 0,
|
||||||
|
EvaluationCode: 'string',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
EligibilityCheckResult: 'string',
|
||||||
|
EligibilityCheckDescription: 'string',
|
||||||
|
Title: 'string',
|
||||||
|
FirstName: 'string',
|
||||||
|
SecondName: 'string',
|
||||||
|
ThirdName: 'string',
|
||||||
|
LastName: 'string',
|
||||||
|
FullName: 'string',
|
||||||
|
EmbossName: 'string',
|
||||||
|
PlaceOfBirth: 'string',
|
||||||
|
DateOfBirth: '2025-05-26',
|
||||||
|
LocalizedDateOfBirth: '2025-05-26',
|
||||||
|
Age: 20,
|
||||||
|
Gender: 'M',
|
||||||
|
Married: 'S',
|
||||||
|
Nationality: 'str',
|
||||||
|
IdType: 'st',
|
||||||
|
IdNumber: 'string',
|
||||||
|
IdExpiryDate: '2025-05-26',
|
||||||
|
EducationLevel: 'stri',
|
||||||
|
ProfessionCode: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
14
src/common/modules/neoleap/controllers/neotest.controller.ts
Normal file
14
src/common/modules/neoleap/controllers/neotest.controller.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { Controller, Get } from '@nestjs/common';
|
||||||
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { NeoLeapService } from '../services/neoleap.service';
|
||||||
|
|
||||||
|
@Controller('neotest')
|
||||||
|
@ApiTags('NeoTest')
|
||||||
|
export class NeoTestController {
|
||||||
|
constructor(private readonly neoleapService: NeoLeapService) {}
|
||||||
|
|
||||||
|
@Get('inquire-application')
|
||||||
|
async inquireApplication() {
|
||||||
|
return this.neoleapService.inquireApplication('1234567890');
|
||||||
|
}
|
||||||
|
}
|
||||||
1
src/common/modules/neoleap/dtos/response/index.ts
Normal file
1
src/common/modules/neoleap/dtos/response/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './inquire-application.response';
|
||||||
@ -0,0 +1,133 @@
|
|||||||
|
import { Expose, Transform } from 'class-transformer';
|
||||||
|
|
||||||
|
export class InquireApplicationResponse {
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.ApplicationNumber)
|
||||||
|
@Expose()
|
||||||
|
applicationNumber!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.ExternalApplicationNumber)
|
||||||
|
@Expose()
|
||||||
|
externalApplicationNumber!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.ApplicationStatus)
|
||||||
|
@Expose()
|
||||||
|
applicationStatus!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.Organization)
|
||||||
|
@Expose()
|
||||||
|
organization!: number;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.Product)
|
||||||
|
@Expose()
|
||||||
|
product!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.ApplicatonDate)
|
||||||
|
@Expose()
|
||||||
|
applicationDate!: string;
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.ApplicationSource)
|
||||||
|
@Expose()
|
||||||
|
applicationSource!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.SalesSource)
|
||||||
|
@Expose()
|
||||||
|
salesSource!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.DeliveryMethod)
|
||||||
|
@Expose()
|
||||||
|
deliveryMethod!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.ProgramCode)
|
||||||
|
@Expose()
|
||||||
|
ProgramCode!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.Plastic)
|
||||||
|
@Expose()
|
||||||
|
plastic!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.Design)
|
||||||
|
@Expose()
|
||||||
|
design!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.ProcessStage)
|
||||||
|
@Expose()
|
||||||
|
processStage!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.ProcessStageStatus)
|
||||||
|
@Expose()
|
||||||
|
processStageStatus!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.EligibilityCheckResult)
|
||||||
|
@Expose()
|
||||||
|
eligibilityCheckResult!: string;
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.EligibilityCheckDescription)
|
||||||
|
@Expose()
|
||||||
|
eligibilityCheckDescription!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.Title)
|
||||||
|
@Expose()
|
||||||
|
title!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.FirstName)
|
||||||
|
@Expose()
|
||||||
|
firstName!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.SecondName)
|
||||||
|
@Expose()
|
||||||
|
secondName!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.ThirdName)
|
||||||
|
@Expose()
|
||||||
|
thirdName!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.LastName)
|
||||||
|
@Expose()
|
||||||
|
lastName!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.FullName)
|
||||||
|
@Expose()
|
||||||
|
fullName!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.EmbossName)
|
||||||
|
@Expose()
|
||||||
|
embossName!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.PlaceOfBirth)
|
||||||
|
@Expose()
|
||||||
|
placeOfBirth!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.DateOfBirth)
|
||||||
|
@Expose()
|
||||||
|
dateOfBirth!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.LocalizedDateOfBirth)
|
||||||
|
@Expose()
|
||||||
|
localizedDateOfBirth!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.Age)
|
||||||
|
@Expose()
|
||||||
|
age!: number;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.Gender)
|
||||||
|
@Expose()
|
||||||
|
gender!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails?.Married)
|
||||||
|
@Expose()
|
||||||
|
married!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails.Nationality)
|
||||||
|
@Expose()
|
||||||
|
nationality!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails.IdType)
|
||||||
|
@Expose()
|
||||||
|
idType!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails.IdNumber)
|
||||||
|
@Expose()
|
||||||
|
idNumber!: string;
|
||||||
|
|
||||||
|
@Transform(({ obj }) => obj.ApplicationDetails.IdExpiryDate)
|
||||||
|
@Expose()
|
||||||
|
idExpiryDate!: string;
|
||||||
|
}
|
||||||
@ -1,2 +1,3 @@
|
|||||||
export * from './create-application.request.interface';
|
export * from './create-application.request.interface';
|
||||||
|
export * from './inquire-application.request.interface';
|
||||||
export * from './neoleap-header.request.interface';
|
export * from './neoleap-header.request.interface';
|
||||||
|
|||||||
@ -0,0 +1,22 @@
|
|||||||
|
import { INeoleapHeaderRequest } from './neoleap-header.request.interface';
|
||||||
|
|
||||||
|
export interface IInquireApplicationRequest extends INeoleapHeaderRequest {
|
||||||
|
InquireApplicationRequestDetails: {
|
||||||
|
ApplicationIdentifier: {
|
||||||
|
InstitutionCode: string;
|
||||||
|
ExternalApplicationNumber: string;
|
||||||
|
};
|
||||||
|
AdditionalData?: {
|
||||||
|
ReturnApplicationType?: boolean;
|
||||||
|
ReturnApplicationStatus?: boolean;
|
||||||
|
ReturnAddresses?: boolean;
|
||||||
|
ReturnBranch?: boolean;
|
||||||
|
ReturnHistory?: boolean;
|
||||||
|
ReturnCard?: boolean;
|
||||||
|
ReturnCustomer?: boolean;
|
||||||
|
ReturnAccount?: boolean;
|
||||||
|
ReturnDirectDebitDetails?: boolean;
|
||||||
|
};
|
||||||
|
HistoryTypeFilterList?: number[];
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -1,8 +1,11 @@
|
|||||||
|
import { HttpModule } from '@nestjs/axios';
|
||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
import { NeoTestController } from './controllers/neotest.controller';
|
||||||
|
import { NeoLeapService } from './services/neoleap.service';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [],
|
imports: [HttpModule],
|
||||||
controllers: [],
|
controllers: [NeoTestController],
|
||||||
providers: [],
|
providers: [NeoLeapService],
|
||||||
})
|
})
|
||||||
export class NeoLeapModule {}
|
export class NeoLeapModule {}
|
||||||
|
|||||||
@ -1,11 +1,14 @@
|
|||||||
import { HttpService } from '@nestjs/axios';
|
import { HttpService } from '@nestjs/axios';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { ConfigService } from '@nestjs/config';
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
import { plainToInstance } from 'class-transformer';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import { CountriesNumericISO } from '~/common/constants';
|
import { CountriesNumericISO } from '~/common/constants';
|
||||||
import { Customer } from '~/customer/entities';
|
import { Customer } from '~/customer/entities';
|
||||||
import { Gender } from '~/customer/enums';
|
import { Gender } from '~/customer/enums';
|
||||||
|
import { INQUIRE_APPLICATION_MOCK } from '../__mocks__/';
|
||||||
|
import { InquireApplicationResponse } from '../dtos/response';
|
||||||
import { ICreateApplicationRequest, INeoleapHeaderRequest } from '../interfaces';
|
import { ICreateApplicationRequest, INeoleapHeaderRequest } from '../interfaces';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class NeoLeapService {
|
export class NeoLeapService {
|
||||||
@ -55,7 +58,7 @@ export class NeoLeapService {
|
|||||||
Title: customer.gender === Gender.MALE ? 'Mr' : 'Ms',
|
Title: customer.gender === Gender.MALE ? 'Mr' : 'Ms',
|
||||||
Gender: customer.gender === Gender.MALE ? 'M' : 'F',
|
Gender: customer.gender === Gender.MALE ? 'M' : 'F',
|
||||||
LocalizedDateOfBirth: moment(customer.dateOfBirth).format('YYYY-MM-DD'),
|
LocalizedDateOfBirth: moment(customer.dateOfBirth).format('YYYY-MM-DD'),
|
||||||
Nationality: '682',
|
Nationality: CountriesNumericISO[customer.countryOfResidence],
|
||||||
},
|
},
|
||||||
ApplicationAddress: {
|
ApplicationAddress: {
|
||||||
City: customer.city,
|
City: customer.city,
|
||||||
@ -75,7 +78,7 @@ export class NeoLeapService {
|
|||||||
...this.prepareHeaders('CreateNewApplication'),
|
...this.prepareHeaders('CreateNewApplication'),
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await this.httpService.axiosRef.post(`${this.baseUrl}/create-application`, payload, {
|
const response = await this.httpService.axiosRef.post(`${this.baseUrl}/application/CreateNewApplication`, payload, {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
Authorization: `${this.apiKey}`,
|
Authorization: `${this.apiKey}`,
|
||||||
@ -85,6 +88,48 @@ export class NeoLeapService {
|
|||||||
//@TODO handle response
|
//@TODO handle response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async inquireApplication(externalApplicationNumber: string) {
|
||||||
|
const responseKey = 'InquireApplicationResponseDetails';
|
||||||
|
if (this.useMock) {
|
||||||
|
return plainToInstance(InquireApplicationResponse, INQUIRE_APPLICATION_MOCK[responseKey], {
|
||||||
|
excludeExtraneousValues: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
InquireApplicationRequestDetails: {
|
||||||
|
ApplicationIdentifier: {
|
||||||
|
InstitutionCode: this.institutionCode,
|
||||||
|
ExternalApplicationNumber: externalApplicationNumber,
|
||||||
|
},
|
||||||
|
AdditionalData: {
|
||||||
|
ReturnApplicationType: true,
|
||||||
|
ReturnApplicationStatus: true,
|
||||||
|
ReturnCard: true,
|
||||||
|
ReturnCustomer: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
...this.prepareHeaders('InquireApplication'),
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await this.httpService.axiosRef.post(`${this.baseUrl}/application/InquireApplication`, payload, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: `${this.apiKey}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.data?.[responseKey]) {
|
||||||
|
return plainToInstance(InquireApplicationResponse, response.data[responseKey], {
|
||||||
|
excludeExtraneousValues: true,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
throw new Error('Invalid response from NeoLeap API');
|
||||||
|
}
|
||||||
|
|
||||||
|
//@TODO handle response
|
||||||
|
}
|
||||||
|
|
||||||
private prepareHeaders(serviceName: string): INeoleapHeaderRequest {
|
private prepareHeaders(serviceName: string): INeoleapHeaderRequest {
|
||||||
return {
|
return {
|
||||||
RequestHeader: {
|
RequestHeader: {
|
||||||
|
|||||||
Reference in New Issue
Block a user