mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 21:00:31 +00:00
236 lines
6.6 KiB
TypeScript
236 lines
6.6 KiB
TypeScript
import moment from 'moment';
|
|
import { difference } from 'lodash';
|
|
import { Service, Inject } from 'typedi';
|
|
import { ServiceError } from 'exceptions';
|
|
import {
|
|
EventDispatcher,
|
|
EventDispatcherInterface,
|
|
} from 'decorators/eventDispatcher';
|
|
import {
|
|
IExchangeRateDTO,
|
|
IExchangeRate,
|
|
IExchangeRatesService,
|
|
IExchangeRateEditDTO,
|
|
IExchangeRateFilter,
|
|
} from 'interfaces';
|
|
import TenancyService from 'services/Tenancy/TenancyService';
|
|
|
|
const ERRORS = {
|
|
NOT_FOUND_EXCHANGE_RATES: 'NOT_FOUND_EXCHANGE_RATES',
|
|
EXCHANGE_RATE_PERIOD_EXISTS: 'EXCHANGE_RATE_PERIOD_EXISTS',
|
|
EXCHANGE_RATE_NOT_FOUND: 'EXCHANGE_RATE_NOT_FOUND',
|
|
};
|
|
|
|
@Service()
|
|
export default class ExchangeRatesService implements IExchangeRatesService {
|
|
@Inject('logger')
|
|
logger: any;
|
|
|
|
@EventDispatcher()
|
|
eventDispatcher: EventDispatcherInterface;
|
|
|
|
@Inject()
|
|
tenancy: TenancyService;
|
|
|
|
/**
|
|
* Creates a new exchange rate.
|
|
* @param {number} tenantId
|
|
* @param {IExchangeRateDTO} exchangeRateDTO
|
|
* @returns {Promise<IExchangeRate>}
|
|
*/
|
|
public async newExchangeRate(
|
|
tenantId: number,
|
|
exchangeRateDTO: IExchangeRateDTO
|
|
): Promise<IExchangeRate> {
|
|
const { ExchangeRate } = this.tenancy.models(tenantId);
|
|
|
|
this.logger.info('[exchange_rates] trying to insert new exchange rate.', {
|
|
tenantId,
|
|
exchangeRateDTO,
|
|
});
|
|
await this.validateExchangeRatePeriodExistance(tenantId, exchangeRateDTO);
|
|
|
|
const exchangeRate = await ExchangeRate.query().insertAndFetch({
|
|
...exchangeRateDTO,
|
|
date: moment(exchangeRateDTO.date).format('YYYY-MM-DD'),
|
|
});
|
|
this.logger.info('[exchange_rates] inserted successfully.', {
|
|
tenantId,
|
|
exchangeRateDTO,
|
|
});
|
|
return exchangeRate;
|
|
}
|
|
|
|
/**
|
|
* Edits the exchange rate details.
|
|
* @param {number} tenantId - Tenant id.
|
|
* @param {number} exchangeRateId - Exchange rate id.
|
|
* @param {IExchangeRateEditDTO} editExRateDTO - Edit exchange rate DTO.
|
|
*/
|
|
public async editExchangeRate(
|
|
tenantId: number,
|
|
exchangeRateId: number,
|
|
editExRateDTO: IExchangeRateEditDTO
|
|
): Promise<void> {
|
|
const { ExchangeRate } = this.tenancy.models(tenantId);
|
|
|
|
this.logger.info('[exchange_rates] trying to edit exchange rate.', {
|
|
tenantId,
|
|
exchangeRateId,
|
|
editExRateDTO,
|
|
});
|
|
await this.validateExchangeRateExistance(tenantId, exchangeRateId);
|
|
|
|
await ExchangeRate.query()
|
|
.where('id', exchangeRateId)
|
|
.update({ ...editExRateDTO });
|
|
this.logger.info('[exchange_rates] exchange rate edited successfully.', {
|
|
tenantId,
|
|
exchangeRateId,
|
|
editExRateDTO,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Deletes the given exchange rate.
|
|
* @param {number} tenantId - Tenant id.
|
|
* @param {number} exchangeRateId - Exchange rate id.
|
|
*/
|
|
public async deleteExchangeRate(
|
|
tenantId: number,
|
|
exchangeRateId: number
|
|
): Promise<void> {
|
|
const { ExchangeRate } = this.tenancy.models(tenantId);
|
|
await this.validateExchangeRateExistance(tenantId, exchangeRateId);
|
|
|
|
await ExchangeRate.query().findById(exchangeRateId).delete();
|
|
}
|
|
|
|
/**
|
|
* Listing exchange rates details.
|
|
* @param {number} tenantId - Tenant id.
|
|
* @param {IExchangeRateFilter} exchangeRateFilter - Exchange rates list filter.
|
|
*/
|
|
public async listExchangeRates(
|
|
tenantId: number,
|
|
exchangeRateFilter: IExchangeRateFilter
|
|
): Promise<void> {
|
|
const { ExchangeRate } = this.tenancy.models(tenantId);
|
|
const exchangeRates = await ExchangeRate.query().pagination(
|
|
exchangeRateFilter.page - 1,
|
|
exchangeRateFilter.pageSize
|
|
);
|
|
|
|
return exchangeRates;
|
|
}
|
|
|
|
/**
|
|
* Deletes exchange rates in bulk.
|
|
* @param {number} tenantId
|
|
* @param {number[]} exchangeRatesIds
|
|
*/
|
|
public async deleteBulkExchangeRates(
|
|
tenantId: number,
|
|
exchangeRatesIds: number[]
|
|
): Promise<void> {
|
|
const { ExchangeRate } = this.tenancy.models(tenantId);
|
|
|
|
this.logger.info('[exchange_rates] trying delete in bulk.', {
|
|
tenantId,
|
|
exchangeRatesIds,
|
|
});
|
|
await this.validateExchangeRatesIdsExistance(tenantId, exchangeRatesIds);
|
|
|
|
await ExchangeRate.query().whereIn('id', exchangeRatesIds).delete();
|
|
this.logger.info('[exchange_rates] deleted successfully.', {
|
|
tenantId,
|
|
exchangeRatesIds,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Validates period of the exchange rate existance.
|
|
* @param {number} tenantId - Tenant id.
|
|
* @param {IExchangeRateDTO} exchangeRateDTO - Exchange rate DTO.
|
|
* @return {Promise<void>}
|
|
*/
|
|
private async validateExchangeRatePeriodExistance(
|
|
tenantId: number,
|
|
exchangeRateDTO: IExchangeRateDTO
|
|
): Promise<void> {
|
|
const { ExchangeRate } = this.tenancy.models(tenantId);
|
|
|
|
this.logger.info('[exchange_rates] trying to validate period existance.', {
|
|
tenantId,
|
|
});
|
|
const foundExchangeRate = await ExchangeRate.query()
|
|
.where('currency_code', exchangeRateDTO.currencyCode)
|
|
.where('date', exchangeRateDTO.date);
|
|
|
|
if (foundExchangeRate.length > 0) {
|
|
this.logger.info('[exchange_rates] given exchange rate period exists.', {
|
|
tenantId,
|
|
});
|
|
throw new ServiceError(ERRORS.EXCHANGE_RATE_PERIOD_EXISTS);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Validate the given echange rate id existance.
|
|
* @param {number} tenantId - Tenant id.
|
|
* @param {number} exchangeRateId - Exchange rate id.
|
|
* @returns {Promise<void>}
|
|
*/
|
|
private async validateExchangeRateExistance(
|
|
tenantId: number,
|
|
exchangeRateId: number
|
|
) {
|
|
const { ExchangeRate } = this.tenancy.models(tenantId);
|
|
|
|
this.logger.info(
|
|
'[exchange_rates] trying to validate exchange rate id existance.',
|
|
{ tenantId, exchangeRateId }
|
|
);
|
|
const foundExchangeRate = await ExchangeRate.query().findById(
|
|
exchangeRateId
|
|
);
|
|
|
|
if (!foundExchangeRate) {
|
|
this.logger.info('[exchange_rates] exchange rate not found.', {
|
|
tenantId,
|
|
exchangeRateId,
|
|
});
|
|
throw new ServiceError(ERRORS.EXCHANGE_RATE_NOT_FOUND);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Validates exchange rates ids existance.
|
|
* @param {number} tenantId - Tenant id.
|
|
* @param {number[]} exchangeRatesIds - Exchange rates ids.
|
|
* @returns {Promise<void>}
|
|
*/
|
|
private async validateExchangeRatesIdsExistance(
|
|
tenantId: number,
|
|
exchangeRatesIds: number[]
|
|
): Promise<void> {
|
|
const { ExchangeRate } = this.tenancy.models(tenantId);
|
|
|
|
const storedExchangeRates = await ExchangeRate.query().whereIn(
|
|
'id',
|
|
exchangeRatesIds
|
|
);
|
|
const storedExchangeRatesIds = storedExchangeRates.map(
|
|
(category) => category.id
|
|
);
|
|
const notFoundExRates = difference(
|
|
exchangeRatesIds,
|
|
storedExchangeRatesIds
|
|
);
|
|
|
|
if (notFoundExRates.length > 0) {
|
|
throw new ServiceError(ERRORS.NOT_FOUND_EXCHANGE_RATES);
|
|
}
|
|
}
|
|
}
|