- Adiciona variáveis globais do Node.js (process, console, __dirname, require, module, exports) - Adiciona variáveis globais do Jest (describe, it, beforeEach, fail, etc.) - Configura ESLint para arquivos JavaScript de configuração - Remove diretivas eslint-disable não utilizadas - Corrige variáveis não usadas prefixando com _ - Ajusta regras do ESLint para ignorar variáveis que começam com _ - Formata código com Prettier
464 lines
16 KiB
TypeScript
464 lines
16 KiB
TypeScript
import {
|
|
Injectable,
|
|
HttpException,
|
|
HttpStatus,
|
|
Inject,
|
|
Logger,
|
|
} from '@nestjs/common';
|
|
import { DataConsultRepository } from './data-consult.repository';
|
|
import { StoreDto } from './dto/store.dto';
|
|
import { SellerDto } from './dto/seller.dto';
|
|
import { BillingDto } from './dto/billing.dto';
|
|
import { CustomerDto } from './dto/customer.dto';
|
|
import { ProductDto } from './dto/product.dto';
|
|
import { RegionDto } from './dto/region.dto';
|
|
import { CarrierDto, FindCarriersDto } from './dto/carrier.dto';
|
|
import { RedisClientToken } from '../core/configs/cache/redis-client.adapter.provider';
|
|
import { IRedisClient } from '../core/configs/cache/IRedisClient';
|
|
import { getOrSetCache } from '../shared/cache.util';
|
|
import { DataSource } from 'typeorm';
|
|
import { DATA_SOURCE } from '../core/constants';
|
|
|
|
@Injectable()
|
|
export class DataConsultService {
|
|
private readonly logger = new Logger(DataConsultService.name);
|
|
private readonly SELLERS_CACHE_KEY = 'data-consult:sellers';
|
|
private readonly SELLERS_TTL = 3600;
|
|
private readonly STORES_TTL = 3600;
|
|
private readonly BILLINGS_TTL = 3600;
|
|
private readonly ALL_PRODUCTS_CACHE_KEY = 'data-consult:products:all';
|
|
private readonly ALL_PRODUCTS_TTL = 600;
|
|
private readonly CUSTOMERS_TTL = 3600;
|
|
private readonly CARRIERS_CACHE_KEY = 'data-consult:carriers:all';
|
|
private readonly CARRIERS_TTL = 3600;
|
|
private readonly REGIONS_CACHE_KEY = 'data-consult:regions';
|
|
private readonly REGIONS_TTL = 7200;
|
|
|
|
constructor(
|
|
private readonly repository: DataConsultRepository,
|
|
@Inject(RedisClientToken) private readonly redisClient: IRedisClient,
|
|
@Inject(DATA_SOURCE) private readonly dataSource: DataSource,
|
|
) {}
|
|
|
|
async stores(): Promise<StoreDto[]> {
|
|
this.logger.log('Buscando todas as lojas');
|
|
try {
|
|
const stores = await this.repository.findStores();
|
|
|
|
if (stores === null || stores === undefined) {
|
|
throw new HttpException(
|
|
'Resultado inválido do repositório',
|
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
|
);
|
|
}
|
|
|
|
const storesArray = Array.isArray(stores) ? stores : [stores];
|
|
|
|
return storesArray
|
|
.filter((store) => {
|
|
if (!store || typeof store !== 'object') {
|
|
return false;
|
|
}
|
|
const hasId =
|
|
store.id !== undefined && store.id !== null && store.id !== '';
|
|
const hasName =
|
|
store.name !== undefined &&
|
|
store.name !== null &&
|
|
store.name !== '';
|
|
const hasStore =
|
|
store.store !== undefined &&
|
|
store.store !== null &&
|
|
store.store !== '';
|
|
return hasId && hasName && hasStore;
|
|
})
|
|
.map((store) => new StoreDto(store));
|
|
} catch (error) {
|
|
this.logger.error('Erro ao buscar lojas', error);
|
|
throw new HttpException(
|
|
'Erro ao buscar lojas',
|
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
|
);
|
|
}
|
|
}
|
|
|
|
async sellers(): Promise<SellerDto[]> {
|
|
this.logger.log('Buscando vendedores com cache Redis...');
|
|
try {
|
|
return await getOrSetCache<SellerDto[]>(
|
|
this.redisClient,
|
|
this.SELLERS_CACHE_KEY,
|
|
this.SELLERS_TTL,
|
|
async () => {
|
|
try {
|
|
const sellers = await this.repository.findSellers();
|
|
|
|
if (sellers === null || sellers === undefined) {
|
|
throw new HttpException(
|
|
'Resultado inválido do repositório',
|
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
|
);
|
|
}
|
|
|
|
const sellersArray = Array.isArray(sellers) ? sellers : [sellers];
|
|
|
|
return sellersArray
|
|
.filter((seller) => {
|
|
if (!seller || typeof seller !== 'object') {
|
|
return false;
|
|
}
|
|
const hasId =
|
|
seller.id !== undefined &&
|
|
seller.id !== null &&
|
|
seller.id !== '';
|
|
const hasName =
|
|
seller.name !== undefined &&
|
|
seller.name !== null &&
|
|
seller.name !== '';
|
|
return hasId && hasName;
|
|
})
|
|
.map((seller) => new SellerDto(seller));
|
|
} catch (error) {
|
|
this.logger.error('Erro ao buscar vendedores', error);
|
|
throw error;
|
|
}
|
|
},
|
|
);
|
|
} catch (error) {
|
|
this.logger.error('Erro ao buscar vendedores', error);
|
|
throw new HttpException(
|
|
'Erro ao buscar vendedores',
|
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
|
);
|
|
}
|
|
}
|
|
|
|
async billings(): Promise<BillingDto[]> {
|
|
this.logger.log('Buscando informações de faturamento');
|
|
try {
|
|
const billings = await this.repository.findBillings();
|
|
|
|
if (billings === null || billings === undefined) {
|
|
throw new HttpException(
|
|
'Resultado inválido do repositório',
|
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
|
);
|
|
}
|
|
|
|
const billingsArray = Array.isArray(billings) ? billings : [billings];
|
|
|
|
return billingsArray
|
|
.filter((billing) => {
|
|
if (!billing || typeof billing !== 'object') {
|
|
return false;
|
|
}
|
|
const hasId =
|
|
billing.id !== undefined &&
|
|
billing.id !== null &&
|
|
billing.id !== '';
|
|
const hasDate = billing.date !== undefined && billing.date !== null;
|
|
const hasTotal =
|
|
billing.total !== undefined && billing.total !== null;
|
|
return hasId && hasDate && hasTotal;
|
|
})
|
|
.map((billing) => new BillingDto(billing));
|
|
} catch (error) {
|
|
this.logger.error('Erro ao buscar faturamento', error);
|
|
throw new HttpException(
|
|
'Erro ao buscar faturamento',
|
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
|
);
|
|
}
|
|
}
|
|
|
|
async customers(filter: string): Promise<CustomerDto[]> {
|
|
this.logger.log(`Buscando clientes com filtro: ${filter}`);
|
|
try {
|
|
if (!filter || typeof filter !== 'string') {
|
|
throw new HttpException('Filtro inválido', HttpStatus.BAD_REQUEST);
|
|
}
|
|
const customers = await this.repository.findCustomers(filter);
|
|
|
|
if (customers === null || customers === undefined) {
|
|
throw new HttpException(
|
|
'Resultado inválido do repositório',
|
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
|
);
|
|
}
|
|
|
|
const customersArray = Array.isArray(customers) ? customers : [customers];
|
|
|
|
return customersArray
|
|
.filter((customer) => {
|
|
if (!customer || typeof customer !== 'object') {
|
|
return false;
|
|
}
|
|
const hasId =
|
|
customer.id !== undefined &&
|
|
customer.id !== null &&
|
|
customer.id !== '';
|
|
const hasName =
|
|
customer.name !== undefined &&
|
|
customer.name !== null &&
|
|
customer.name !== '';
|
|
const hasDocument =
|
|
customer.document !== undefined &&
|
|
customer.document !== null &&
|
|
customer.document !== '';
|
|
return hasId && hasName && hasDocument;
|
|
})
|
|
.map((customer) => new CustomerDto(customer));
|
|
} catch (error) {
|
|
this.logger.error('Erro ao buscar clientes', error);
|
|
throw new HttpException(
|
|
'Erro ao buscar clientes',
|
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
|
);
|
|
}
|
|
}
|
|
|
|
async products(filter: string): Promise<ProductDto[]> {
|
|
this.logger.log(`Buscando produtos com filtro: ${filter}`);
|
|
try {
|
|
if (!filter || typeof filter !== 'string') {
|
|
throw new HttpException('Filtro inválido', HttpStatus.BAD_REQUEST);
|
|
}
|
|
const products = await this.repository.findProducts(filter);
|
|
return products.map((product) => new ProductDto(product));
|
|
} catch (error) {
|
|
this.logger.error('Erro ao buscar produtos', error);
|
|
throw new HttpException(
|
|
'Erro ao buscar produtos',
|
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
|
);
|
|
}
|
|
}
|
|
|
|
async productsByCodauxiliar(codauxiliar: string): Promise<ProductDto[]> {
|
|
this.logger.log(`Buscando produtos por codauxiliar: ${codauxiliar}`);
|
|
try {
|
|
if (!codauxiliar || typeof codauxiliar !== 'string') {
|
|
throw new HttpException(
|
|
'Código auxiliar inválido',
|
|
HttpStatus.BAD_REQUEST,
|
|
);
|
|
}
|
|
const products = await this.repository.findProductsByCodauxiliar(
|
|
codauxiliar,
|
|
);
|
|
return products.map((product) => new ProductDto(product));
|
|
} catch (error) {
|
|
this.logger.error('Erro ao buscar produtos por codauxiliar', error);
|
|
throw new HttpException(
|
|
'Erro ao buscar produtos por codauxiliar',
|
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
|
);
|
|
}
|
|
}
|
|
|
|
async getAllProducts(): Promise<ProductDto[]> {
|
|
this.logger.log('Buscando todos os produtos');
|
|
try {
|
|
return await getOrSetCache<ProductDto[]>(
|
|
this.redisClient,
|
|
this.ALL_PRODUCTS_CACHE_KEY,
|
|
this.ALL_PRODUCTS_TTL,
|
|
async () => {
|
|
try {
|
|
const products = await this.repository.findAllProducts();
|
|
|
|
if (products === null || products === undefined) {
|
|
throw new HttpException(
|
|
'Resultado inválido do repositório',
|
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
|
);
|
|
}
|
|
|
|
const productsArray = Array.isArray(products)
|
|
? products
|
|
: [products];
|
|
|
|
return productsArray
|
|
.filter((product) => {
|
|
if (!product || typeof product !== 'object') {
|
|
return false;
|
|
}
|
|
const hasId =
|
|
product.id !== undefined &&
|
|
product.id !== null &&
|
|
product.id !== '';
|
|
const hasName =
|
|
product.name !== undefined &&
|
|
product.name !== null &&
|
|
product.name !== '';
|
|
const hasManufacturerCode =
|
|
product.manufacturerCode !== undefined &&
|
|
product.manufacturerCode !== null &&
|
|
product.manufacturerCode !== '';
|
|
return hasId && hasName && hasManufacturerCode;
|
|
})
|
|
.map((product) => new ProductDto(product));
|
|
} catch (error) {
|
|
this.logger.error('Erro ao buscar todos os produtos', error);
|
|
throw error;
|
|
}
|
|
},
|
|
);
|
|
} catch (error) {
|
|
this.logger.error('Erro ao buscar todos os produtos', error);
|
|
throw new HttpException(
|
|
'Erro ao buscar produtos',
|
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
|
);
|
|
}
|
|
}
|
|
|
|
async getAllCarriers(): Promise<CarrierDto[]> {
|
|
this.logger.log('Buscando todas as transportadoras');
|
|
try {
|
|
return await getOrSetCache<CarrierDto[]>(
|
|
this.redisClient,
|
|
this.CARRIERS_CACHE_KEY,
|
|
this.CARRIERS_TTL,
|
|
async () => {
|
|
try {
|
|
const carriers = await this.repository.findAllCarriers();
|
|
|
|
if (carriers === null || carriers === undefined) {
|
|
throw new HttpException(
|
|
'Resultado inválido do repositório',
|
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
|
);
|
|
}
|
|
|
|
const carriersArray = Array.isArray(carriers)
|
|
? carriers
|
|
: [carriers];
|
|
|
|
return carriersArray
|
|
.filter((carrier) => {
|
|
if (!carrier || typeof carrier !== 'object') {
|
|
return false;
|
|
}
|
|
const hasCarrierId =
|
|
carrier.carrierId !== undefined &&
|
|
carrier.carrierId !== null &&
|
|
carrier.carrierId !== '';
|
|
const hasCarrierName =
|
|
carrier.carrierName !== undefined &&
|
|
carrier.carrierName !== null &&
|
|
carrier.carrierName !== '';
|
|
const hasCarrierDescription =
|
|
carrier.carrierDescription !== undefined &&
|
|
carrier.carrierDescription !== null &&
|
|
carrier.carrierDescription !== '';
|
|
return hasCarrierId && hasCarrierName && hasCarrierDescription;
|
|
})
|
|
.map((carrier) => ({
|
|
carrierId: carrier.carrierId?.toString() || '',
|
|
carrierName: carrier.carrierName || '',
|
|
carrierDescription: carrier.carrierDescription || '',
|
|
}));
|
|
} catch (error) {
|
|
this.logger.error('Erro ao buscar transportadoras', error);
|
|
throw error;
|
|
}
|
|
},
|
|
);
|
|
} catch (error) {
|
|
this.logger.error('Erro ao buscar transportadoras', error);
|
|
throw new HttpException(
|
|
'Erro ao buscar transportadoras',
|
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
|
);
|
|
}
|
|
}
|
|
|
|
async getCarriersByDate(query: FindCarriersDto): Promise<CarrierDto[]> {
|
|
this.logger.log(
|
|
`Buscando transportadoras por período: ${JSON.stringify(query)}`,
|
|
);
|
|
try {
|
|
const carriers = await this.repository.findCarriersByDate(query);
|
|
return carriers.map((carrier) => ({
|
|
carrierId: carrier.carrierId?.toString() || '',
|
|
carrierName: carrier.carrierName || '',
|
|
carrierDescription: carrier.carrierDescription || '',
|
|
ordersCount: carrier.ordersCount ? Number(carrier.ordersCount) : 0,
|
|
}));
|
|
} catch (error) {
|
|
this.logger.error('Erro ao buscar transportadoras por período', error);
|
|
throw new HttpException(
|
|
'Erro ao buscar transportadoras',
|
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
|
);
|
|
}
|
|
}
|
|
|
|
async getOrderCarriers(orderId: number): Promise<CarrierDto[]> {
|
|
this.logger.log(`Buscando transportadoras do pedido: ${orderId}`);
|
|
try {
|
|
const carriers = await this.repository.findOrderCarriers(orderId);
|
|
return carriers.map((carrier) => ({
|
|
carrierId: carrier.carrierId?.toString() || '',
|
|
carrierName: carrier.carrierName || '',
|
|
carrierDescription: carrier.carrierDescription || '',
|
|
}));
|
|
} catch (error) {
|
|
this.logger.error('Erro ao buscar transportadoras do pedido', error);
|
|
throw new HttpException(
|
|
'Erro ao buscar transportadoras do pedido',
|
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
|
);
|
|
}
|
|
}
|
|
|
|
async getRegions(): Promise<RegionDto[]> {
|
|
this.logger.log('Buscando todas as regiões');
|
|
try {
|
|
return await getOrSetCache<RegionDto[]>(
|
|
this.redisClient,
|
|
this.REGIONS_CACHE_KEY,
|
|
this.REGIONS_TTL,
|
|
async () => {
|
|
try {
|
|
const regions = await this.repository.findRegions();
|
|
|
|
if (regions === null || regions === undefined) {
|
|
throw new HttpException(
|
|
'Resultado inválido do repositório',
|
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
|
);
|
|
}
|
|
|
|
const regionsArray = Array.isArray(regions) ? regions : [regions];
|
|
|
|
return regionsArray
|
|
.filter((region) => {
|
|
if (!region || typeof region !== 'object') {
|
|
return false;
|
|
}
|
|
const hasNumregiao =
|
|
region.numregiao !== undefined && region.numregiao !== null;
|
|
const hasRegiao =
|
|
region.regiao !== undefined &&
|
|
region.regiao !== null &&
|
|
region.regiao !== '';
|
|
return hasNumregiao && hasRegiao;
|
|
})
|
|
.map((region) => new RegionDto(region));
|
|
} catch (error) {
|
|
this.logger.error('Erro ao buscar regiões', error);
|
|
throw error;
|
|
}
|
|
},
|
|
);
|
|
} catch (error) {
|
|
this.logger.error('Erro ao buscar regiões', error);
|
|
throw new HttpException(
|
|
'Erro ao buscar regiões',
|
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
|
);
|
|
}
|
|
}
|
|
}
|