mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-21 15:20:34 +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 { Service, Inject } from 'typedi';
|
||||||
import { Router, Request, Response, NextFunction } from 'express';
|
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 asyncMiddleware from '@/api/middleware/asyncMiddleware';
|
||||||
import BaseController from './BaseController';
|
import BaseController from './BaseController';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
import { ExchangeRatesService } from '@/services/ExchangeRates/ExchangeRatesService';
|
|
||||||
import { EchangeRateErrors } from '@/lib/ExchangeRate/types';
|
import { EchangeRateErrors } from '@/lib/ExchangeRate/types';
|
||||||
|
import { ExchangeRateApplication } from '@/services/ExchangeRates/ExchangeRateApplication';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class ExchangeRatesController extends BaseController {
|
export default class ExchangeRatesController extends BaseController {
|
||||||
@Inject()
|
@Inject()
|
||||||
private exchangeRatesService: ExchangeRatesService;
|
private exchangeRatesApp: ExchangeRateApplication;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor method.
|
* Constructor method.
|
||||||
@@ -43,7 +43,7 @@ export default class ExchangeRatesController extends BaseController {
|
|||||||
const exchangeRateQuery = this.matchedQueryData(req);
|
const exchangeRateQuery = this.matchedQueryData(req);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const exchangeRate = await this.exchangeRatesService.latest(
|
const exchangeRate = await this.exchangeRatesApp.latest(
|
||||||
tenantId,
|
tenantId,
|
||||||
exchangeRateQuery
|
exchangeRateQuery
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,36 +1,9 @@
|
|||||||
import { IFilterRole } from './DynamicFilter';
|
export interface ExchangeRateLatestDTO {
|
||||||
|
toCurrency: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IExchangeRate {
|
export interface EchangeRateLatestPOJO {
|
||||||
id: number,
|
baseCurrency: string;
|
||||||
currencyCode: string,
|
toCurrency: string;
|
||||||
exchangeRate: number,
|
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>;
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ export class OpenExchangeRate implements IExchangeRateService {
|
|||||||
baseCurrency: string,
|
baseCurrency: string,
|
||||||
toCurrency: string
|
toCurrency: string
|
||||||
): Promise<number> {
|
): Promise<number> {
|
||||||
|
// Vaclidates the Open Exchange Rate api id early.
|
||||||
|
this.validateApiIdExistance();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await Axios.get(OPEN_EXCHANGE_RATE_LATEST_URL, {
|
const result = await Axios.get(OPEN_EXCHANGE_RATE_LATEST_URL, {
|
||||||
params: {
|
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.
|
* Handles the latest errors.
|
||||||
* @param {any} error
|
* @param {any} error
|
||||||
|
* @throws {ServiceError}
|
||||||
*/
|
*/
|
||||||
private handleLatestErrors(error: any) {
|
private handleLatestErrors(error: any) {
|
||||||
if (error.response.data?.message === 'missing_app_id') {
|
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 { Service } from 'typedi';
|
||||||
import { IExchangeRatesService } from '@/interfaces';
|
|
||||||
import { ExchangeRate } from '@/lib/ExchangeRate/ExchangeRate';
|
import { ExchangeRate } from '@/lib/ExchangeRate/ExchangeRate';
|
||||||
import { ExchangeRateServiceType } from '@/lib/ExchangeRate/types';
|
import { ExchangeRateServiceType } from '@/lib/ExchangeRate/types';
|
||||||
interface ExchangeRateLatestDTO {
|
import { EchangeRateLatestPOJO, ExchangeRateLatestDTO } from '@/interfaces';
|
||||||
toCurrency: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface EchangeRateLatestPOJO {
|
|
||||||
baseCurrency: string;
|
|
||||||
toCurrency: string;
|
|
||||||
exchangeRate: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class ExchangeRatesService {
|
export class ExchangeRatesService {
|
||||||
|
|||||||
Reference in New Issue
Block a user