119 lines
3.1 KiB
TypeScript
119 lines
3.1 KiB
TypeScript
import { Repository } from 'typeorm';
|
|
import { AppDataSource } from '../../config/typeorm.js';
|
|
import { Currency } from './entities/currency.entity.js';
|
|
import { NotFoundError, ConflictError } from '../../shared/errors/index.js';
|
|
import { logger } from '../../shared/utils/logger.js';
|
|
|
|
export interface CreateCurrencyDto {
|
|
code: string;
|
|
name: string;
|
|
symbol: string;
|
|
decimal_places?: number;
|
|
decimals?: number; // Accept camelCase too
|
|
}
|
|
|
|
export interface UpdateCurrencyDto {
|
|
name?: string;
|
|
symbol?: string;
|
|
decimal_places?: number;
|
|
decimals?: number; // Accept camelCase too
|
|
active?: boolean;
|
|
}
|
|
|
|
class CurrenciesService {
|
|
private repository: Repository<Currency>;
|
|
|
|
constructor() {
|
|
this.repository = AppDataSource.getRepository(Currency);
|
|
}
|
|
|
|
async findAll(activeOnly: boolean = false): Promise<Currency[]> {
|
|
logger.debug('Finding all currencies', { activeOnly });
|
|
|
|
const queryBuilder = this.repository
|
|
.createQueryBuilder('currency')
|
|
.orderBy('currency.code', 'ASC');
|
|
|
|
if (activeOnly) {
|
|
queryBuilder.where('currency.active = :active', { active: true });
|
|
}
|
|
|
|
return queryBuilder.getMany();
|
|
}
|
|
|
|
async findById(id: string): Promise<Currency> {
|
|
logger.debug('Finding currency by id', { id });
|
|
|
|
const currency = await this.repository.findOne({
|
|
where: { id },
|
|
});
|
|
|
|
if (!currency) {
|
|
throw new NotFoundError('Moneda no encontrada');
|
|
}
|
|
|
|
return currency;
|
|
}
|
|
|
|
async findByCode(code: string): Promise<Currency | null> {
|
|
logger.debug('Finding currency by code', { code });
|
|
|
|
return this.repository.findOne({
|
|
where: { code: code.toUpperCase() },
|
|
});
|
|
}
|
|
|
|
async create(dto: CreateCurrencyDto): Promise<Currency> {
|
|
logger.debug('Creating currency', { code: dto.code });
|
|
|
|
const existing = await this.findByCode(dto.code);
|
|
if (existing) {
|
|
throw new ConflictError(`Ya existe una moneda con código ${dto.code}`);
|
|
}
|
|
|
|
// Accept both snake_case and camelCase
|
|
const decimals = dto.decimal_places ?? dto.decimals ?? 2;
|
|
|
|
const currency = this.repository.create({
|
|
code: dto.code.toUpperCase(),
|
|
name: dto.name,
|
|
symbol: dto.symbol,
|
|
decimals,
|
|
});
|
|
|
|
const saved = await this.repository.save(currency);
|
|
logger.info('Currency created', { id: saved.id, code: saved.code });
|
|
|
|
return saved;
|
|
}
|
|
|
|
async update(id: string, dto: UpdateCurrencyDto): Promise<Currency> {
|
|
logger.debug('Updating currency', { id });
|
|
|
|
const currency = await this.findById(id);
|
|
|
|
// Accept both snake_case and camelCase
|
|
const decimals = dto.decimal_places ?? dto.decimals;
|
|
|
|
if (dto.name !== undefined) {
|
|
currency.name = dto.name;
|
|
}
|
|
if (dto.symbol !== undefined) {
|
|
currency.symbol = dto.symbol;
|
|
}
|
|
if (decimals !== undefined) {
|
|
currency.decimals = decimals;
|
|
}
|
|
if (dto.active !== undefined) {
|
|
currency.active = dto.active;
|
|
}
|
|
|
|
const updated = await this.repository.save(currency);
|
|
logger.info('Currency updated', { id: updated.id, code: updated.code });
|
|
|
|
return updated;
|
|
}
|
|
}
|
|
|
|
export const currenciesService = new CurrenciesService();
|