mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-08-25 05:42:27 +00:00
feat: handle card status changed webhook
This commit is contained in:
@ -10,7 +10,7 @@ import {
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
import { Customer } from '~/customer/entities';
|
||||
import { CardColors, CardIssuers, CardScheme, CardStatus, CustomerType } from '../enums';
|
||||
import { CardColors, CardIssuers, CardScheme, CardStatus, CardStatusDescription, CustomerType } from '../enums';
|
||||
import { Account } from './account.entity';
|
||||
import { Transaction } from './transaction.entity';
|
||||
|
||||
@ -41,6 +41,12 @@ export class Card {
|
||||
@Column({ type: 'varchar', nullable: false, default: CardStatus.PENDING })
|
||||
status!: CardStatus;
|
||||
|
||||
@Column({ type: 'varchar', nullable: false, default: CardStatusDescription.PENDING_ACTIVATION })
|
||||
statusDescription!: CardStatusDescription;
|
||||
|
||||
@Column({ type: 'decimal', precision: 10, scale: 2, default: 0.0, name: 'limit' })
|
||||
limit!: number;
|
||||
|
||||
@Column({ type: 'varchar', nullable: false, default: CardScheme.VISA })
|
||||
scheme!: CardScheme;
|
||||
|
||||
|
68
src/card/enums/card-status-description.enum.ts
Normal file
68
src/card/enums/card-status-description.enum.ts
Normal file
@ -0,0 +1,68 @@
|
||||
/**
|
||||
* import { CardStatus, CardStatusDescription } from '../enums';
|
||||
|
||||
export const CardStatusMapper: Record<string, { description: CardStatusDescription; status: CardStatus }> = {
|
||||
//ACTIVE
|
||||
'00': { description: 'NORMAL', status: CardStatus.ACTIVE },
|
||||
|
||||
//PENDING
|
||||
'02': { description: 'NOT_YET_ISSUED', status: CardStatus.PENDING },
|
||||
'20': { description: 'PENDING_ISSUANCE', status: CardStatus.PENDING },
|
||||
'21': { description: 'CARD_EXTRACTED', status: CardStatus.PENDING },
|
||||
'22': { description: 'EXTRACTION_FAILED', status: CardStatus.PENDING },
|
||||
'23': { description: 'FAILED_PRINTING_BULK', status: CardStatus.PENDING },
|
||||
'24': { description: 'FAILED_PRINTING_INST', status: CardStatus.PENDING },
|
||||
'30': { description: 'PENDING_ACTIVATION', status: CardStatus.PENDING },
|
||||
'27': { description: 'PENDING_PIN', status: CardStatus.PENDING },
|
||||
'16': { description: 'PREPARE_TO_CLOSE', status: CardStatus.PENDING },
|
||||
|
||||
//BLOCKED
|
||||
'01': { description: 'PIN_TRIES_EXCEEDED', status: CardStatus.BLOCKED },
|
||||
'03': { description: 'CARD_EXPIRED', status: CardStatus.BLOCKED },
|
||||
'04': { description: 'LOST', status: CardStatus.BLOCKED },
|
||||
'05': { description: 'STOLEN', status: CardStatus.BLOCKED },
|
||||
'06': { description: 'CUSTOMER_CLOSE', status: CardStatus.BLOCKED },
|
||||
'07': { description: 'BANK_CANCELLED', status: CardStatus.BLOCKED },
|
||||
'08': { description: 'FRAUD', status: CardStatus.BLOCKED },
|
||||
'09': { description: 'DAMAGED', status: CardStatus.BLOCKED },
|
||||
'50': { description: 'SAFE_BLOCK', status: CardStatus.BLOCKED },
|
||||
'51': { description: 'TEMPORARY_BLOCK', status: CardStatus.BLOCKED },
|
||||
'52': { description: 'RISK_BLOCK', status: CardStatus.BLOCKED },
|
||||
'53': { description: 'OVERDRAFT', status: CardStatus.BLOCKED },
|
||||
'54': { description: 'BLOCKED_FOR_FEES', status: CardStatus.BLOCKED },
|
||||
'67': { description: 'CLOSED_CUSTOMER_DEAD', status: CardStatus.BLOCKED },
|
||||
'75': { description: 'RETURN_CARD', status: CardStatus.BLOCKED },
|
||||
|
||||
//Fallback
|
||||
'99': { description: 'UNKNOWN', status: CardStatus.PENDING },
|
||||
};
|
||||
|
||||
*/
|
||||
export enum CardStatusDescription {
|
||||
NORMAL = 'NORMAL',
|
||||
NOT_YET_ISSUED = 'NOT_YET_ISSUED',
|
||||
PENDING_ISSUANCE = 'PENDING_ISSUANCE',
|
||||
CARD_EXTRACTED = 'CARD_EXTRACTED',
|
||||
EXTRACTION_FAILED = 'EXTRACTION_FAILED',
|
||||
FAILED_PRINTING_BULK = 'FAILED_PRINTING_BULK',
|
||||
FAILED_PRINTING_INST = 'FAILED_PRINTING_INST',
|
||||
PENDING_ACTIVATION = 'PENDING_ACTIVATION',
|
||||
PENDING_PIN = 'PENDING_PIN',
|
||||
PREPARE_TO_CLOSE = 'PREPARE_TO_CLOSE',
|
||||
PIN_TRIES_EXCEEDED = 'PIN_TRIES_EXCEEDED',
|
||||
CARD_EXPIRED = 'CARD_EXPIRED',
|
||||
LOST = 'LOST',
|
||||
STOLEN = 'STOLEN',
|
||||
CUSTOMER_CLOSE = 'CUSTOMER_CLOSE',
|
||||
BANK_CANCELLED = 'BANK_CANCELLED',
|
||||
FRAUD = 'FRAUD',
|
||||
DAMAGED = 'DAMAGED',
|
||||
SAFE_BLOCK = 'SAFE_BLOCK',
|
||||
TEMPORARY_BLOCK = 'TEMPORARY_BLOCK',
|
||||
RISK_BLOCK = 'RISK_BLOCK',
|
||||
OVERDRAFT = 'OVERDRAFT',
|
||||
BLOCKED_FOR_FEES = 'BLOCKED_FOR_FEES',
|
||||
CLOSED_CUSTOMER_DEAD = 'CLOSED_CUSTOMER_DEAD',
|
||||
RETURN_CARD = 'RETURN_CARD',
|
||||
UNKNOWN = 'UNKNOWN',
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
export * from './card-colors.enum';
|
||||
export * from './card-issuers.enum';
|
||||
export * from './card-scheme.enum';
|
||||
export * from './card-status-description.enum';
|
||||
export * from './card-status.enum';
|
||||
export * from './customer-type.enum';
|
||||
export * from './transaction-scope.enum';
|
||||
|
109
src/card/mappers/card-status-description.mapper.ts
Normal file
109
src/card/mappers/card-status-description.mapper.ts
Normal file
@ -0,0 +1,109 @@
|
||||
import { UserLocale } from '~/core/enums';
|
||||
import { CardStatusDescription } from '../enums';
|
||||
|
||||
export const CardStatusMapper: Record<CardStatusDescription, { [key in UserLocale]: { description: string } }> = {
|
||||
[CardStatusDescription.NORMAL]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card is active' },
|
||||
[UserLocale.ARABIC]: { description: 'البطاقة نشطة' },
|
||||
},
|
||||
[CardStatusDescription.NOT_YET_ISSUED]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card is not yet issued' },
|
||||
[UserLocale.ARABIC]: { description: 'البطاقة لم تصدر بعد' },
|
||||
},
|
||||
[CardStatusDescription.PENDING_ISSUANCE]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card is pending issuance' },
|
||||
[UserLocale.ARABIC]: { description: 'البطاقة قيد الإصدار' },
|
||||
},
|
||||
[CardStatusDescription.CARD_EXTRACTED]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card has been extracted' },
|
||||
[UserLocale.ARABIC]: { description: 'تم استخراج البطاقة' },
|
||||
},
|
||||
[CardStatusDescription.EXTRACTION_FAILED]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card extraction has failed' },
|
||||
[UserLocale.ARABIC]: { description: 'فشل استخراج البطاقة' },
|
||||
},
|
||||
[CardStatusDescription.FAILED_PRINTING_BULK]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card printing in bulk has failed' },
|
||||
[UserLocale.ARABIC]: { description: 'فشل الطباعة بالجملة للبطاقة' },
|
||||
},
|
||||
[CardStatusDescription.FAILED_PRINTING_INST]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card printing in institution has failed' },
|
||||
[UserLocale.ARABIC]: { description: 'فشل الطباعة في المؤسسة للبطاقة' },
|
||||
},
|
||||
[CardStatusDescription.PENDING_ACTIVATION]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card is pending activation' },
|
||||
[UserLocale.ARABIC]: { description: 'البطاقة قيد التفعيل' },
|
||||
},
|
||||
[CardStatusDescription.PENDING_PIN]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card is pending PIN' },
|
||||
[UserLocale.ARABIC]: { description: 'البطاقة قيد الانتظار لرقم التعريف الشخصي' },
|
||||
},
|
||||
[CardStatusDescription.PREPARE_TO_CLOSE]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card is being prepared for closure' },
|
||||
[UserLocale.ARABIC]: { description: 'البطاقة قيد التحضير للإغلاق' },
|
||||
},
|
||||
[CardStatusDescription.PIN_TRIES_EXCEEDED]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card PIN tries have been exceeded' },
|
||||
[UserLocale.ARABIC]: { description: 'تم تجاوز محاولات رقم التعريف الشخصي للبطاقة' },
|
||||
},
|
||||
[CardStatusDescription.CARD_EXPIRED]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card has expired' },
|
||||
[UserLocale.ARABIC]: { description: 'انتهت صلاحية البطاقة' },
|
||||
},
|
||||
[CardStatusDescription.LOST]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card is lost' },
|
||||
[UserLocale.ARABIC]: { description: 'البطاقة ضائعة' },
|
||||
},
|
||||
[CardStatusDescription.STOLEN]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card is stolen' },
|
||||
[UserLocale.ARABIC]: { description: 'البطاقة مسروقة' },
|
||||
},
|
||||
[CardStatusDescription.CUSTOMER_CLOSE]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card is being closed by the customer' },
|
||||
[UserLocale.ARABIC]: { description: 'البطاقة قيد الإغلاق من قبل العميل' },
|
||||
},
|
||||
[CardStatusDescription.BANK_CANCELLED]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card has been cancelled by the bank' },
|
||||
[UserLocale.ARABIC]: { description: 'البطاقة ألغيت من قبل البنك' },
|
||||
},
|
||||
[CardStatusDescription.FRAUD]: {
|
||||
[UserLocale.ENGLISH]: { description: 'Fraud' },
|
||||
[UserLocale.ARABIC]: { description: 'احتيال' },
|
||||
},
|
||||
[CardStatusDescription.DAMAGED]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card is damaged' },
|
||||
[UserLocale.ARABIC]: { description: 'البطاقة تالفة' },
|
||||
},
|
||||
[CardStatusDescription.SAFE_BLOCK]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card is in a safe block' },
|
||||
[UserLocale.ARABIC]: { description: 'البطاقة في حظر آمن' },
|
||||
},
|
||||
[CardStatusDescription.TEMPORARY_BLOCK]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card is in a temporary block' },
|
||||
[UserLocale.ARABIC]: { description: 'البطاقة في حظر مؤقت' },
|
||||
},
|
||||
[CardStatusDescription.RISK_BLOCK]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card is in a risk block' },
|
||||
[UserLocale.ARABIC]: { description: 'البطاقة في حظر المخاطر' },
|
||||
},
|
||||
[CardStatusDescription.OVERDRAFT]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card is in overdraft' },
|
||||
[UserLocale.ARABIC]: { description: 'البطاقة في السحب على المكشوف' },
|
||||
},
|
||||
[CardStatusDescription.BLOCKED_FOR_FEES]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card is blocked for fees' },
|
||||
[UserLocale.ARABIC]: { description: 'البطاقة محظورة للرسوم' },
|
||||
},
|
||||
[CardStatusDescription.CLOSED_CUSTOMER_DEAD]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card is closed because the customer is dead' },
|
||||
[UserLocale.ARABIC]: { description: 'البطاقة مغلقة لأن العميل متوفى' },
|
||||
},
|
||||
[CardStatusDescription.RETURN_CARD]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card is being returned' },
|
||||
[UserLocale.ARABIC]: { description: 'البطاقة قيد الإرجاع' },
|
||||
},
|
||||
[CardStatusDescription.UNKNOWN]: {
|
||||
[UserLocale.ENGLISH]: { description: 'The card status is unknown' },
|
||||
[UserLocale.ARABIC]: { description: 'حالة البطاقة غير معروفة' },
|
||||
},
|
||||
};
|
37
src/card/mappers/card-status.mapper.ts
Normal file
37
src/card/mappers/card-status.mapper.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import { CardStatus, CardStatusDescription } from '../enums';
|
||||
|
||||
export const CardStatusMapper: Record<string, { description: CardStatusDescription; status: CardStatus }> = {
|
||||
//ACTIVE
|
||||
'00': { description: CardStatusDescription.NORMAL, status: CardStatus.ACTIVE },
|
||||
|
||||
//PENDING
|
||||
'02': { description: CardStatusDescription.NOT_YET_ISSUED, status: CardStatus.PENDING },
|
||||
'20': { description: CardStatusDescription.PENDING_ISSUANCE, status: CardStatus.PENDING },
|
||||
'21': { description: CardStatusDescription.CARD_EXTRACTED, status: CardStatus.PENDING },
|
||||
'22': { description: CardStatusDescription.EXTRACTION_FAILED, status: CardStatus.PENDING },
|
||||
'23': { description: CardStatusDescription.FAILED_PRINTING_BULK, status: CardStatus.PENDING },
|
||||
'24': { description: CardStatusDescription.FAILED_PRINTING_INST, status: CardStatus.PENDING },
|
||||
'30': { description: CardStatusDescription.PENDING_ACTIVATION, status: CardStatus.PENDING },
|
||||
'27': { description: CardStatusDescription.PENDING_PIN, status: CardStatus.PENDING },
|
||||
'16': { description: CardStatusDescription.PREPARE_TO_CLOSE, status: CardStatus.PENDING },
|
||||
|
||||
//BLOCKED
|
||||
'01': { description: CardStatusDescription.PIN_TRIES_EXCEEDED, status: CardStatus.BLOCKED },
|
||||
'03': { description: CardStatusDescription.CARD_EXPIRED, status: CardStatus.BLOCKED },
|
||||
'04': { description: CardStatusDescription.LOST, status: CardStatus.BLOCKED },
|
||||
'05': { description: CardStatusDescription.STOLEN, status: CardStatus.BLOCKED },
|
||||
'06': { description: CardStatusDescription.CUSTOMER_CLOSE, status: CardStatus.BLOCKED },
|
||||
'07': { description: CardStatusDescription.BANK_CANCELLED, status: CardStatus.BLOCKED },
|
||||
'08': { description: CardStatusDescription.FRAUD, status: CardStatus.BLOCKED },
|
||||
'09': { description: CardStatusDescription.DAMAGED, status: CardStatus.BLOCKED },
|
||||
'50': { description: CardStatusDescription.SAFE_BLOCK, status: CardStatus.BLOCKED },
|
||||
'51': { description: CardStatusDescription.TEMPORARY_BLOCK, status: CardStatus.BLOCKED },
|
||||
'52': { description: CardStatusDescription.RISK_BLOCK, status: CardStatus.BLOCKED },
|
||||
'53': { description: CardStatusDescription.OVERDRAFT, status: CardStatus.BLOCKED },
|
||||
'54': { description: CardStatusDescription.BLOCKED_FOR_FEES, status: CardStatus.BLOCKED },
|
||||
'67': { description: CardStatusDescription.CLOSED_CUSTOMER_DEAD, status: CardStatus.BLOCKED },
|
||||
'75': { description: CardStatusDescription.RETURN_CARD, status: CardStatus.BLOCKED },
|
||||
|
||||
//Fallback
|
||||
'99': { description: CardStatusDescription.UNKNOWN, status: CardStatus.PENDING },
|
||||
};
|
@ -3,7 +3,7 @@ import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { CreateApplicationResponse } from '~/common/modules/neoleap/dtos/response';
|
||||
import { Card } from '../entities';
|
||||
import { CardColors, CardIssuers, CardScheme, CardStatus, CustomerType } from '../enums';
|
||||
import { CardColors, CardIssuers, CardScheme, CardStatus, CardStatusDescription, CustomerType } from '../enums';
|
||||
|
||||
@Injectable()
|
||||
export class CardRepository {
|
||||
@ -19,7 +19,6 @@ export class CardRepository {
|
||||
firstSixDigits: card.firstSixDigits,
|
||||
lastFourDigits: card.lastFourDigits,
|
||||
color: CardColors.BLUE,
|
||||
status: CardStatus.ACTIVE,
|
||||
scheme: CardScheme.VISA,
|
||||
issuer: CardIssuers.NEOLEAP,
|
||||
accountId: accountId,
|
||||
@ -40,4 +39,11 @@ export class CardRepository {
|
||||
where: { customerId, status: CardStatus.ACTIVE },
|
||||
});
|
||||
}
|
||||
|
||||
updateCardStatus(id: string, status: CardStatus, statusDescription: CardStatusDescription) {
|
||||
return this.cardRepository.update(id, {
|
||||
status: status,
|
||||
statusDescription: statusDescription,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
import { BadRequestException, Injectable } from '@nestjs/common';
|
||||
import { Transactional } from 'typeorm-transactional';
|
||||
import { AccountCardStatusChangedWebhookRequest } from '~/common/modules/neoleap/dtos/requests';
|
||||
import { CreateApplicationResponse } from '~/common/modules/neoleap/dtos/response';
|
||||
import { Card } from '../entities';
|
||||
import { CardStatusMapper } from '../mappers/card-status.mapper';
|
||||
import { CardRepository } from '../repositories';
|
||||
import { AccountService } from './account.service';
|
||||
|
||||
@ -42,4 +44,11 @@ export class CardService {
|
||||
}
|
||||
return card;
|
||||
}
|
||||
|
||||
async updateCardStatus(body: AccountCardStatusChangedWebhookRequest) {
|
||||
const card = await this.getCardByReferenceNumber(body.cardId);
|
||||
const { description, status } = CardStatusMapper[body.newStatus] || CardStatusMapper['99'];
|
||||
|
||||
return this.cardRepository.updateCardStatus(card.id, status, description);
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,29 @@
|
||||
import { Body, Controller, Post } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { TransactionService } from '~/card/services/transaction.service';
|
||||
import { AccountTransactionWebhookRequest, CardTransactionWebhookRequest } from '../dtos/requests';
|
||||
import {
|
||||
AccountCardStatusChangedWebhookRequest,
|
||||
AccountTransactionWebhookRequest,
|
||||
CardTransactionWebhookRequest,
|
||||
} from '../dtos/requests';
|
||||
import { NeoLeapWebhookService } from '../services';
|
||||
|
||||
@Controller('neoleap-webhooks')
|
||||
@ApiTags('Neoleap Webhooks')
|
||||
export class NeoLeapWebhooksController {
|
||||
constructor(private readonly transactionService: TransactionService) {}
|
||||
constructor(private readonly neoleapWebhookService: NeoLeapWebhookService) {}
|
||||
|
||||
@Post('card-transaction')
|
||||
async handleCardTransactionWebhook(@Body() body: CardTransactionWebhookRequest) {
|
||||
return this.transactionService.createCardTransaction(body);
|
||||
return this.neoleapWebhookService.handleCardTransactionWebhook(body);
|
||||
}
|
||||
|
||||
@Post('account-transaction')
|
||||
async handleAccountTransactionWebhook(@Body() body: AccountTransactionWebhookRequest) {
|
||||
return this.transactionService.createAccountTransaction(body);
|
||||
return this.neoleapWebhookService.handleAccountTransactionWebhook(body);
|
||||
}
|
||||
|
||||
@Post('account-card-status-changed')
|
||||
async handleAccountCardStatusChangedWebhook(@Body() body: AccountCardStatusChangedWebhookRequest) {
|
||||
return this.neoleapWebhookService.handleAccountCardStatusChangedWebhook(body);
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ export class NeoTestController {
|
||||
@ApiDataResponse(InquireApplicationResponse)
|
||||
async inquireApplication(@AuthenticatedUser() user: IJwtPayload) {
|
||||
const customer = await this.customerService.findCustomerById(user.sub);
|
||||
const data = await this.neoleapService.inquireApplication(customer.waitingNumber.toString());
|
||||
const data = await this.neoleapService.inquireApplication(customer.applicationNumber.toString());
|
||||
return ResponseFactory.data(data);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,20 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Expose } from 'class-transformer';
|
||||
import { IsString } from 'class-validator';
|
||||
|
||||
export class AccountCardStatusChangedWebhookRequest {
|
||||
@ApiProperty()
|
||||
@Expose({ name: 'InstId' })
|
||||
@IsString()
|
||||
instId!: string;
|
||||
|
||||
@ApiProperty()
|
||||
@Expose({ name: 'cardId' })
|
||||
@IsString()
|
||||
cardId!: string;
|
||||
|
||||
@ApiProperty()
|
||||
@Expose({ name: 'newStatus' })
|
||||
@IsString()
|
||||
newStatus!: string;
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
export * from './account-card-status-changed-webhook.request.dto';
|
||||
export * from './account-transaction-webhook.request.dto';
|
||||
export * from './card-transaction-webhook.request.dto';
|
||||
export * from './update-card-controls.request.dto';
|
||||
|
@ -4,11 +4,12 @@ import { CardModule } from '~/card/card.module';
|
||||
import { CustomerModule } from '~/customer/customer.module';
|
||||
import { NeoLeapWebhooksController } from './controllers/neoleap-webhooks.controller';
|
||||
import { NeoTestController } from './controllers/neotest.controller';
|
||||
import { NeoLeapWebhookService } from './services';
|
||||
import { NeoLeapService } from './services/neoleap.service';
|
||||
|
||||
@Module({
|
||||
imports: [HttpModule, CustomerModule, CardModule],
|
||||
controllers: [NeoTestController, NeoLeapWebhooksController],
|
||||
providers: [NeoLeapService],
|
||||
providers: [NeoLeapService, NeoLeapWebhookService],
|
||||
})
|
||||
export class NeoLeapModule {}
|
||||
|
@ -0,0 +1,2 @@
|
||||
export * from './neoleap-webook.service';
|
||||
export * from './neoleap.service';
|
||||
|
@ -0,0 +1,25 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { CardService } from '~/card/services';
|
||||
import { TransactionService } from '~/card/services/transaction.service';
|
||||
import {
|
||||
AccountCardStatusChangedWebhookRequest,
|
||||
AccountTransactionWebhookRequest,
|
||||
CardTransactionWebhookRequest,
|
||||
} from '../dtos/requests';
|
||||
|
||||
@Injectable()
|
||||
export class NeoLeapWebhookService {
|
||||
constructor(private readonly transactionService: TransactionService, private readonly cardService: CardService) {}
|
||||
|
||||
handleCardTransactionWebhook(body: CardTransactionWebhookRequest) {
|
||||
return this.transactionService.createCardTransaction(body);
|
||||
}
|
||||
|
||||
handleAccountTransactionWebhook(body: AccountTransactionWebhookRequest) {
|
||||
return this.transactionService.createAccountTransaction(body);
|
||||
}
|
||||
|
||||
handleAccountCardStatusChangedWebhook(body: AccountCardStatusChangedWebhookRequest) {
|
||||
return this.cardService.updateCardStatus(body);
|
||||
}
|
||||
}
|
@ -50,7 +50,7 @@ export class NeoLeapService {
|
||||
CreateNewApplicationRequestDetails: {
|
||||
ApplicationRequestDetails: {
|
||||
InstitutionCode: this.institutionCode,
|
||||
ExternalApplicationNumber: customer.waitingNumber.toString(),
|
||||
ExternalApplicationNumber: customer.applicationNumber.toString(),
|
||||
ApplicationType: '01',
|
||||
Product: '1101',
|
||||
ApplicationDate: moment().format('YYYY-MM-DD'),
|
||||
|
@ -1,4 +1,8 @@
|
||||
export enum UserLocale {
|
||||
ARABIC = 'ar',
|
||||
ENGLISH = 'en',
|
||||
}
|
||||
import { ObjectValues } from '../types';
|
||||
|
||||
export const UserLocale = {
|
||||
ARABIC: 'ar',
|
||||
ENGLISH: 'en',
|
||||
} as const;
|
||||
|
||||
export type UserLocale = ObjectValues<typeof UserLocale>;
|
||||
|
@ -97,7 +97,7 @@ export class CustomerResponseDto {
|
||||
this.gender = customer.gender;
|
||||
this.isJunior = customer.isJunior;
|
||||
this.isGuardian = customer.isGuardian;
|
||||
this.waitingNumber = customer.waitingNumber;
|
||||
this.waitingNumber = customer.applicationNumber;
|
||||
this.country = customer.country;
|
||||
this.region = customer.region;
|
||||
this.city = customer.city;
|
||||
|
@ -71,9 +71,9 @@ export class Customer extends BaseEntity {
|
||||
@Column('boolean', { default: false, name: 'is_guardian' })
|
||||
isGuardian!: boolean;
|
||||
|
||||
@Column('int', { name: 'waiting_number' })
|
||||
@Column('int', { name: 'application_number' })
|
||||
@Generated('increment')
|
||||
waitingNumber!: number;
|
||||
applicationNumber!: number;
|
||||
|
||||
@Column('varchar', { name: 'user_id' })
|
||||
userId!: string;
|
||||
|
16
src/db/migrations/1753098116701-update-card-table.ts
Normal file
16
src/db/migrations/1753098116701-update-card-table.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class UpdateCardTable1753098116701 implements MigrationInterface {
|
||||
name = 'UpdateCardTable1753098116701'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "cards" ADD "statusDescription" character varying NOT NULL DEFAULT 'PENDING_ACTIVATION'`);
|
||||
await queryRunner.query(`ALTER TABLE "cards" ADD "limit" numeric(10,2) NOT NULL DEFAULT '0'`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "cards" DROP COLUMN "limit"`);
|
||||
await queryRunner.query(`ALTER TABLE "cards" DROP COLUMN "statusDescription"`);
|
||||
}
|
||||
|
||||
}
|
16
src/db/migrations/1753098326876-edit-customer-table.ts
Normal file
16
src/db/migrations/1753098326876-edit-customer-table.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class EditCustomerTable1753098326876 implements MigrationInterface {
|
||||
name = 'EditCustomerTable1753098326876'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "customers" RENAME COLUMN "waiting_number" TO "application_number"`);
|
||||
await queryRunner.query(`ALTER SEQUENCE "customers_waiting_number_seq" RENAME TO "customers_application_number_seq"`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER SEQUENCE "customers_application_number_seq" RENAME TO "customers_waiting_number_seq"`);
|
||||
await queryRunner.query(`ALTER TABLE "customers" RENAME COLUMN "application_number" TO "waiting_number"`);
|
||||
}
|
||||
|
||||
}
|
@ -29,3 +29,5 @@ export * from './1749633935436-create-card-entity';
|
||||
export * from './1751456987627-create-account-entity';
|
||||
export * from './1751466314709-create-transaction-table';
|
||||
export * from './1752056898465-edit-transaction-table';
|
||||
export * from './1753098116701-update-card-table';
|
||||
export * from './1753098326876-edit-customer-table';
|
||||
|
Reference in New Issue
Block a user