mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 13:50:31 +00:00
feat(server): add application layer to exchange rate service
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
import { Service, Inject } from 'typedi';
|
||||
import { Router, Request, Response, NextFunction } from 'express';
|
||||
import { check, param, query } from 'express-validator';
|
||||
import { query } from 'express-validator';
|
||||
import asyncMiddleware from '@/api/middleware/asyncMiddleware';
|
||||
import BaseController from './BaseController';
|
||||
import { ServiceError } from '@/exceptions';
|
||||
import { ExchangeRatesService } from '@/services/ExchangeRates/ExchangeRatesService';
|
||||
import { EchangeRateErrors } from '@/lib/ExchangeRate/types';
|
||||
import { ExchangeRateApplication } from '@/services/ExchangeRates/ExchangeRateApplication';
|
||||
|
||||
@Service()
|
||||
export default class ExchangeRatesController extends BaseController {
|
||||
@Inject()
|
||||
private exchangeRatesService: ExchangeRatesService;
|
||||
private exchangeRatesApp: ExchangeRateApplication;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
@@ -43,7 +43,7 @@ export default class ExchangeRatesController extends BaseController {
|
||||
const exchangeRateQuery = this.matchedQueryData(req);
|
||||
|
||||
try {
|
||||
const exchangeRate = await this.exchangeRatesService.latest(
|
||||
const exchangeRate = await this.exchangeRatesApp.latest(
|
||||
tenantId,
|
||||
exchangeRateQuery
|
||||
);
|
||||
|
||||
@@ -1,36 +1,9 @@
|
||||
import { IFilterRole } from './DynamicFilter';
|
||||
export interface ExchangeRateLatestDTO {
|
||||
toCurrency: string;
|
||||
}
|
||||
|
||||
export interface IExchangeRate {
|
||||
id: number,
|
||||
currencyCode: string,
|
||||
exchangeRate: number,
|
||||
date: Date,
|
||||
createdAt: Date,
|
||||
updatedAt: Date,
|
||||
};
|
||||
|
||||
export interface IExchangeRateDTO {
|
||||
currencyCode: string,
|
||||
exchangeRate: number,
|
||||
date: Date,
|
||||
};
|
||||
|
||||
export interface IExchangeRateEditDTO {
|
||||
exchangeRate: number,
|
||||
};
|
||||
|
||||
export interface IExchangeRateFilter {
|
||||
page: number,
|
||||
pageSize: number,
|
||||
filterRoles?: IFilterRole[];
|
||||
columnSortBy: string;
|
||||
sortOrder: string;
|
||||
};
|
||||
|
||||
export interface IExchangeRatesService {
|
||||
newExchangeRate(tenantId: number, exchangeRateDTO: IExchangeRateDTO): Promise<IExchangeRate>;
|
||||
editExchangeRate(tenantId: number, exchangeRateId: number, editExRateDTO: IExchangeRateEditDTO): Promise<void>;
|
||||
|
||||
deleteExchangeRate(tenantId: number, exchangeRateId: number): Promise<void>;
|
||||
listExchangeRates(tenantId: number, exchangeRateFilter: IExchangeRateFilter): Promise<void>;
|
||||
};
|
||||
export interface EchangeRateLatestPOJO {
|
||||
baseCurrency: string;
|
||||
toCurrency: string;
|
||||
exchangeRate: number;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,9 @@ export class OpenExchangeRate implements IExchangeRateService {
|
||||
baseCurrency: string,
|
||||
toCurrency: string
|
||||
): Promise<number> {
|
||||
// Vaclidates the Open Exchange Rate api id early.
|
||||
this.validateApiIdExistance();
|
||||
|
||||
try {
|
||||
const result = await Axios.get(OPEN_EXCHANGE_RATE_LATEST_URL, {
|
||||
params: {
|
||||
@@ -32,9 +35,25 @@ export class OpenExchangeRate implements IExchangeRateService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the Open Exchange Rate api id.
|
||||
* @throws {ServiceError}
|
||||
*/
|
||||
private validateApiIdExistance() {
|
||||
const apiId = config.exchangeRate.openExchangeRate.appId;
|
||||
|
||||
if (!apiId) {
|
||||
throw new ServiceError(
|
||||
EchangeRateErrors.EX_RATE_SERVICE_API_KEY_REQUIRED,
|
||||
'Invalid App ID provided. Please sign up at https://openexchangerates.org/signup, or contact support@openexchangerates.org.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the latest errors.
|
||||
* @param {any} error
|
||||
* @throws {ServiceError}
|
||||
*/
|
||||
private handleLatestErrors(error: any) {
|
||||
if (error.response.data?.message === 'missing_app_id') {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { Inject } from 'typedi';
|
||||
import { ExchangeRatesService } from './ExchangeRatesService';
|
||||
import { EchangeRateLatestPOJO, ExchangeRateLatestDTO } from '@/interfaces';
|
||||
|
||||
export class ExchangeRateApplication {
|
||||
@Inject()
|
||||
private exchangeRateService: ExchangeRatesService;
|
||||
|
||||
/**
|
||||
* Gets the latest exchange rate.
|
||||
* @param {number} tenantId
|
||||
* @param {ExchangeRateLatestDTO} exchangeRateLatestDTO
|
||||
* @returns {Promise<EchangeRateLatestPOJO>}
|
||||
*/
|
||||
public latest(
|
||||
tenantId: number,
|
||||
exchangeRateLatestDTO: ExchangeRateLatestDTO
|
||||
): Promise<EchangeRateLatestPOJO> {
|
||||
return this.exchangeRateService.latest(tenantId, exchangeRateLatestDTO);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,7 @@
|
||||
import { Service, Inject } from 'typedi';
|
||||
import { IExchangeRatesService } from '@/interfaces';
|
||||
import { Service } from 'typedi';
|
||||
import { ExchangeRate } from '@/lib/ExchangeRate/ExchangeRate';
|
||||
import { ExchangeRateServiceType } from '@/lib/ExchangeRate/types';
|
||||
interface ExchangeRateLatestDTO {
|
||||
toCurrency: string;
|
||||
}
|
||||
|
||||
interface EchangeRateLatestPOJO {
|
||||
baseCurrency: string;
|
||||
toCurrency: string;
|
||||
exchangeRate: number;
|
||||
}
|
||||
import { EchangeRateLatestPOJO, ExchangeRateLatestDTO } from '@/interfaces';
|
||||
|
||||
@Service()
|
||||
export class ExchangeRatesService {
|
||||
|
||||
Reference in New Issue
Block a user