refactor: atualizações e remoção de módulos não utilizados
This commit is contained in:
@@ -1,50 +1,47 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { DataConsultService } from '../data-consult.service';
|
||||
import { DataConsultRepository } from '../data-consult.repository';
|
||||
import { ILogger } from '../../Log/ILogger';
|
||||
import { IRedisClient } from '../../core/configs/cache/IRedisClient';
|
||||
import { RedisClientToken } from '../../core/configs/cache/redis-client.adapter.provider';
|
||||
import { DataSource } from 'typeorm';
|
||||
import { DATA_SOURCE } from '../../core/constants';
|
||||
|
||||
export const createMockRepository = (methods: Partial<DataConsultRepository> = {}) => ({
|
||||
findStores: jest.fn(),
|
||||
findSellers: jest.fn(),
|
||||
findBillings: jest.fn(),
|
||||
findCustomers: jest.fn(),
|
||||
findAllProducts: jest.fn(),
|
||||
findAllCarriers: jest.fn(),
|
||||
findRegions: jest.fn(),
|
||||
...methods,
|
||||
} as any);
|
||||
export const createMockRepository = (
|
||||
methods: Partial<DataConsultRepository> = {},
|
||||
) =>
|
||||
({
|
||||
findStores: jest.fn(),
|
||||
findSellers: jest.fn(),
|
||||
findBillings: jest.fn(),
|
||||
findCustomers: jest.fn(),
|
||||
findAllProducts: jest.fn(),
|
||||
findAllCarriers: jest.fn(),
|
||||
findRegions: jest.fn(),
|
||||
...methods,
|
||||
} as any);
|
||||
|
||||
export const createMockLogger = () => ({
|
||||
log: jest.fn(),
|
||||
error: jest.fn(),
|
||||
warn: jest.fn(),
|
||||
debug: jest.fn(),
|
||||
} as any);
|
||||
|
||||
export const createMockRedisClient = () => ({
|
||||
get: jest.fn().mockResolvedValue(null),
|
||||
set: jest.fn().mockResolvedValue(undefined),
|
||||
} as any);
|
||||
export const createMockRedisClient = () =>
|
||||
({
|
||||
get: jest.fn().mockResolvedValue(null),
|
||||
set: jest.fn().mockResolvedValue(undefined),
|
||||
} as any);
|
||||
|
||||
export interface DataConsultServiceTestContext {
|
||||
service: DataConsultService;
|
||||
mockRepository: jest.Mocked<DataConsultRepository>;
|
||||
mockLogger: jest.Mocked<ILogger>;
|
||||
mockRedisClient: jest.Mocked<IRedisClient>;
|
||||
mockDataSource: jest.Mocked<DataSource>;
|
||||
}
|
||||
|
||||
export async function createDataConsultServiceTestModule(
|
||||
repositoryMethods: Partial<DataConsultRepository> = {},
|
||||
redisClientMethods: Partial<IRedisClient> = {}
|
||||
redisClientMethods: Partial<IRedisClient> = {},
|
||||
): Promise<DataConsultServiceTestContext> {
|
||||
const mockRepository = createMockRepository(repositoryMethods);
|
||||
const mockLogger = createMockLogger();
|
||||
const mockRedisClient = { ...createMockRedisClient(), ...redisClientMethods } as any;
|
||||
const mockRedisClient = {
|
||||
...createMockRedisClient(),
|
||||
...redisClientMethods,
|
||||
} as any;
|
||||
const mockDataSource = {} as any;
|
||||
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
@@ -58,10 +55,6 @@ export async function createDataConsultServiceTestModule(
|
||||
provide: RedisClientToken,
|
||||
useValue: mockRedisClient,
|
||||
},
|
||||
{
|
||||
provide: 'LoggerService',
|
||||
useValue: mockLogger,
|
||||
},
|
||||
{
|
||||
provide: DATA_SOURCE,
|
||||
useValue: mockDataSource,
|
||||
@@ -74,9 +67,7 @@ export async function createDataConsultServiceTestModule(
|
||||
return {
|
||||
service,
|
||||
mockRepository,
|
||||
mockLogger,
|
||||
mockRedisClient,
|
||||
mockDataSource,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ describe('DataConsultService', () => {
|
||||
|
||||
const result = await context.service.stores();
|
||||
|
||||
result.forEach(store => {
|
||||
result.forEach((store) => {
|
||||
expect(store.id).toBeDefined();
|
||||
expect(store.name).toBeDefined();
|
||||
expect(store.store).toBeDefined();
|
||||
@@ -36,7 +36,10 @@ describe('DataConsultService', () => {
|
||||
});
|
||||
|
||||
it('should validate that repository result is an array', async () => {
|
||||
context.mockRepository.findStores.mockResolvedValue({ id: '001', name: 'Loja 1' } as any);
|
||||
context.mockRepository.findStores.mockResolvedValue({
|
||||
id: '001',
|
||||
name: 'Loja 1',
|
||||
} as any);
|
||||
const result = await context.service.stores();
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
});
|
||||
@@ -49,7 +52,7 @@ describe('DataConsultService', () => {
|
||||
] as any);
|
||||
|
||||
const result = await context.service.stores();
|
||||
result.forEach(store => {
|
||||
result.forEach((store) => {
|
||||
expect(store.id).not.toBe('');
|
||||
expect(store.name).not.toBe('');
|
||||
expect(store.store).not.toBe('');
|
||||
@@ -60,7 +63,10 @@ describe('DataConsultService', () => {
|
||||
const repositoryError = new Error('Database connection failed');
|
||||
context.mockRepository.findStores.mockRejectedValue(repositoryError);
|
||||
await expect(context.service.stores()).rejects.toThrow(HttpException);
|
||||
expect(context.mockLogger.error).toHaveBeenCalledWith('Erro ao buscar lojas', repositoryError);
|
||||
expect(context.mockLogger.error).toHaveBeenCalledWith(
|
||||
'Erro ao buscar lojas',
|
||||
repositoryError,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -85,7 +91,7 @@ describe('DataConsultService', () => {
|
||||
] as any);
|
||||
|
||||
const result = await context.service.sellers();
|
||||
result.forEach(seller => {
|
||||
result.forEach((seller) => {
|
||||
expect(seller.id).toBeDefined();
|
||||
expect(seller.name).toBeDefined();
|
||||
});
|
||||
@@ -97,7 +103,10 @@ describe('DataConsultService', () => {
|
||||
});
|
||||
|
||||
it('should validate that repository result is an array', async () => {
|
||||
context.mockRepository.findSellers.mockResolvedValue({ id: '001', name: 'Vendedor 1' } as any);
|
||||
context.mockRepository.findSellers.mockResolvedValue({
|
||||
id: '001',
|
||||
name: 'Vendedor 1',
|
||||
} as any);
|
||||
const result = await context.service.sellers();
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
});
|
||||
@@ -109,7 +118,7 @@ describe('DataConsultService', () => {
|
||||
] as any);
|
||||
|
||||
const result = await context.service.sellers();
|
||||
result.forEach(seller => {
|
||||
result.forEach((seller) => {
|
||||
expect(seller.id).not.toBe('');
|
||||
expect(seller.name).not.toBe('');
|
||||
});
|
||||
@@ -119,7 +128,10 @@ describe('DataConsultService', () => {
|
||||
const repositoryError = new Error('Database connection failed');
|
||||
context.mockRepository.findSellers.mockRejectedValue(repositoryError);
|
||||
await expect(context.service.sellers()).rejects.toThrow(HttpException);
|
||||
expect(context.mockLogger.error).toHaveBeenCalledWith('Erro ao buscar vendedores', repositoryError);
|
||||
expect(context.mockLogger.error).toHaveBeenCalledWith(
|
||||
'Erro ao buscar vendedores',
|
||||
repositoryError,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -144,7 +156,7 @@ describe('DataConsultService', () => {
|
||||
] as any);
|
||||
|
||||
const result = await context.service.billings();
|
||||
result.forEach(billing => {
|
||||
result.forEach((billing) => {
|
||||
expect(billing.id).toBeDefined();
|
||||
expect(billing.date).toBeDefined();
|
||||
expect(billing.total).toBeDefined();
|
||||
@@ -157,7 +169,11 @@ describe('DataConsultService', () => {
|
||||
});
|
||||
|
||||
it('should validate that repository result is an array', async () => {
|
||||
context.mockRepository.findBillings.mockResolvedValue({ id: '001', date: new Date(), total: 1000 } as any);
|
||||
context.mockRepository.findBillings.mockResolvedValue({
|
||||
id: '001',
|
||||
date: new Date(),
|
||||
total: 1000,
|
||||
} as any);
|
||||
const result = await context.service.billings();
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
});
|
||||
@@ -170,7 +186,7 @@ describe('DataConsultService', () => {
|
||||
] as any);
|
||||
|
||||
const result = await context.service.billings();
|
||||
result.forEach(billing => {
|
||||
result.forEach((billing) => {
|
||||
expect(billing.id).not.toBe('');
|
||||
expect(billing.date).toBeDefined();
|
||||
expect(billing.total).toBeDefined();
|
||||
@@ -181,7 +197,10 @@ describe('DataConsultService', () => {
|
||||
const repositoryError = new Error('Database connection failed');
|
||||
context.mockRepository.findBillings.mockRejectedValue(repositoryError);
|
||||
await expect(context.service.billings()).rejects.toThrow(HttpException);
|
||||
expect(context.mockLogger.error).toHaveBeenCalledWith('Erro ao buscar faturamento', repositoryError);
|
||||
expect(context.mockLogger.error).toHaveBeenCalledWith(
|
||||
'Erro ao buscar faturamento',
|
||||
repositoryError,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -206,7 +225,7 @@ describe('DataConsultService', () => {
|
||||
] as any);
|
||||
|
||||
const result = await context.service.customers('test');
|
||||
result.forEach(customer => {
|
||||
result.forEach((customer) => {
|
||||
expect(customer.id).toBeDefined();
|
||||
expect(customer.name).toBeDefined();
|
||||
expect(customer.document).toBeDefined();
|
||||
@@ -219,7 +238,11 @@ describe('DataConsultService', () => {
|
||||
});
|
||||
|
||||
it('should validate that repository result is an array', async () => {
|
||||
context.mockRepository.findCustomers.mockResolvedValue({ id: '001', name: 'Cliente 1', document: '12345678900' } as any);
|
||||
context.mockRepository.findCustomers.mockResolvedValue({
|
||||
id: '001',
|
||||
name: 'Cliente 1',
|
||||
document: '12345678900',
|
||||
} as any);
|
||||
const result = await context.service.customers('test');
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
});
|
||||
@@ -232,7 +255,7 @@ describe('DataConsultService', () => {
|
||||
] as any);
|
||||
|
||||
const result = await context.service.customers('test');
|
||||
result.forEach(customer => {
|
||||
result.forEach((customer) => {
|
||||
expect(customer.id).not.toBe('');
|
||||
expect(customer.name).not.toBe('');
|
||||
expect(customer.document).not.toBe('');
|
||||
@@ -242,8 +265,13 @@ describe('DataConsultService', () => {
|
||||
it('should log error when repository throws exception', async () => {
|
||||
const repositoryError = new Error('Database connection failed');
|
||||
context.mockRepository.findCustomers.mockRejectedValue(repositoryError);
|
||||
await expect(context.service.customers('test')).rejects.toThrow(HttpException);
|
||||
expect(context.mockLogger.error).toHaveBeenCalledWith('Erro ao buscar clientes', repositoryError);
|
||||
await expect(context.service.customers('test')).rejects.toThrow(
|
||||
HttpException,
|
||||
);
|
||||
expect(context.mockLogger.error).toHaveBeenCalledWith(
|
||||
'Erro ao buscar clientes',
|
||||
repositoryError,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -268,7 +296,7 @@ describe('DataConsultService', () => {
|
||||
] as any);
|
||||
|
||||
const result = await context.service.getAllProducts();
|
||||
result.forEach(product => {
|
||||
result.forEach((product) => {
|
||||
expect(product.id).toBeDefined();
|
||||
expect(product.name).toBeDefined();
|
||||
expect(product.manufacturerCode).toBeDefined();
|
||||
@@ -281,7 +309,11 @@ describe('DataConsultService', () => {
|
||||
});
|
||||
|
||||
it('should validate that repository result is an array', async () => {
|
||||
context.mockRepository.findAllProducts.mockResolvedValue({ id: '001', name: 'Produto 1', manufacturerCode: 'FAB001' } as any);
|
||||
context.mockRepository.findAllProducts.mockResolvedValue({
|
||||
id: '001',
|
||||
name: 'Produto 1',
|
||||
manufacturerCode: 'FAB001',
|
||||
} as any);
|
||||
const result = await context.service.getAllProducts();
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
});
|
||||
@@ -294,7 +326,7 @@ describe('DataConsultService', () => {
|
||||
] as any);
|
||||
|
||||
const result = await context.service.getAllProducts();
|
||||
result.forEach(product => {
|
||||
result.forEach((product) => {
|
||||
expect(product.id).not.toBe('');
|
||||
expect(product.name).not.toBe('');
|
||||
expect(product.manufacturerCode).not.toBe('');
|
||||
@@ -303,9 +335,16 @@ describe('DataConsultService', () => {
|
||||
|
||||
it('should log error when repository throws exception', async () => {
|
||||
const repositoryError = new Error('Database connection failed');
|
||||
context.mockRepository.findAllProducts.mockRejectedValue(repositoryError);
|
||||
await expect(context.service.getAllProducts()).rejects.toThrow(HttpException);
|
||||
expect(context.mockLogger.error).toHaveBeenCalledWith('Erro ao buscar todos os produtos', repositoryError);
|
||||
context.mockRepository.findAllProducts.mockRejectedValue(
|
||||
repositoryError,
|
||||
);
|
||||
await expect(context.service.getAllProducts()).rejects.toThrow(
|
||||
HttpException,
|
||||
);
|
||||
expect(context.mockLogger.error).toHaveBeenCalledWith(
|
||||
'Erro ao buscar todos os produtos',
|
||||
repositoryError,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -325,12 +364,19 @@ describe('DataConsultService', () => {
|
||||
it('should validate that all carriers have required properties (carrierId, carrierName, carrierDescription)', async () => {
|
||||
context.mockRepository.findAllCarriers.mockResolvedValue([
|
||||
{ carrierId: '001', carrierName: 'Transportadora 1' },
|
||||
{ carrierName: 'Transportadora 2', carrierDescription: '002 - Transportadora 2' },
|
||||
{ carrierId: '003', carrierName: 'Transportadora 3', carrierDescription: '003 - Transportadora 3' },
|
||||
{
|
||||
carrierName: 'Transportadora 2',
|
||||
carrierDescription: '002 - Transportadora 2',
|
||||
},
|
||||
{
|
||||
carrierId: '003',
|
||||
carrierName: 'Transportadora 3',
|
||||
carrierDescription: '003 - Transportadora 3',
|
||||
},
|
||||
] as any);
|
||||
|
||||
const result = await context.service.getAllCarriers();
|
||||
result.forEach(carrier => {
|
||||
result.forEach((carrier) => {
|
||||
expect(carrier.carrierId).toBeDefined();
|
||||
expect(carrier.carrierName).toBeDefined();
|
||||
expect(carrier.carrierDescription).toBeDefined();
|
||||
@@ -343,20 +389,36 @@ describe('DataConsultService', () => {
|
||||
});
|
||||
|
||||
it('should validate that repository result is an array', async () => {
|
||||
context.mockRepository.findAllCarriers.mockResolvedValue({ carrierId: '001', carrierName: 'Transportadora 1', carrierDescription: '001 - Transportadora 1' } as any);
|
||||
context.mockRepository.findAllCarriers.mockResolvedValue({
|
||||
carrierId: '001',
|
||||
carrierName: 'Transportadora 1',
|
||||
carrierDescription: '001 - Transportadora 1',
|
||||
} as any);
|
||||
const result = await context.service.getAllCarriers();
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
});
|
||||
|
||||
it('should validate that required properties are not empty strings', async () => {
|
||||
context.mockRepository.findAllCarriers.mockResolvedValue([
|
||||
{ carrierId: '', carrierName: 'Transportadora 1', carrierDescription: '001 - Transportadora 1' },
|
||||
{ carrierId: '002', carrierName: '', carrierDescription: '002 - Transportadora 2' },
|
||||
{ carrierId: '003', carrierName: 'Transportadora 3', carrierDescription: '' },
|
||||
{
|
||||
carrierId: '',
|
||||
carrierName: 'Transportadora 1',
|
||||
carrierDescription: '001 - Transportadora 1',
|
||||
},
|
||||
{
|
||||
carrierId: '002',
|
||||
carrierName: '',
|
||||
carrierDescription: '002 - Transportadora 2',
|
||||
},
|
||||
{
|
||||
carrierId: '003',
|
||||
carrierName: 'Transportadora 3',
|
||||
carrierDescription: '',
|
||||
},
|
||||
] as any);
|
||||
|
||||
const result = await context.service.getAllCarriers();
|
||||
result.forEach(carrier => {
|
||||
result.forEach((carrier) => {
|
||||
expect(carrier.carrierId).not.toBe('');
|
||||
expect(carrier.carrierName).not.toBe('');
|
||||
expect(carrier.carrierDescription).not.toBe('');
|
||||
@@ -365,9 +427,16 @@ describe('DataConsultService', () => {
|
||||
|
||||
it('should log error when repository throws exception', async () => {
|
||||
const repositoryError = new Error('Database connection failed');
|
||||
context.mockRepository.findAllCarriers.mockRejectedValue(repositoryError);
|
||||
await expect(context.service.getAllCarriers()).rejects.toThrow(HttpException);
|
||||
expect(context.mockLogger.error).toHaveBeenCalledWith('Erro ao buscar transportadoras', repositoryError);
|
||||
context.mockRepository.findAllCarriers.mockRejectedValue(
|
||||
repositoryError,
|
||||
);
|
||||
await expect(context.service.getAllCarriers()).rejects.toThrow(
|
||||
HttpException,
|
||||
);
|
||||
expect(context.mockLogger.error).toHaveBeenCalledWith(
|
||||
'Erro ao buscar transportadoras',
|
||||
repositoryError,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -392,7 +461,7 @@ describe('DataConsultService', () => {
|
||||
] as any);
|
||||
|
||||
const result = await context.service.getRegions();
|
||||
result.forEach(region => {
|
||||
result.forEach((region) => {
|
||||
expect(region.numregiao).toBeDefined();
|
||||
expect(region.regiao).toBeDefined();
|
||||
});
|
||||
@@ -404,7 +473,10 @@ describe('DataConsultService', () => {
|
||||
});
|
||||
|
||||
it('should validate that repository result is an array', async () => {
|
||||
context.mockRepository.findRegions.mockResolvedValue({ numregiao: 1, regiao: 'Região Sul' } as any);
|
||||
context.mockRepository.findRegions.mockResolvedValue({
|
||||
numregiao: 1,
|
||||
regiao: 'Região Sul',
|
||||
} as any);
|
||||
const result = await context.service.getRegions();
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
});
|
||||
@@ -417,7 +489,7 @@ describe('DataConsultService', () => {
|
||||
] as any);
|
||||
|
||||
const result = await context.service.getRegions();
|
||||
result.forEach(region => {
|
||||
result.forEach((region) => {
|
||||
expect(region.numregiao).toBeDefined();
|
||||
expect(region.numregiao).not.toBeNull();
|
||||
expect(region.regiao).toBeDefined();
|
||||
@@ -428,8 +500,13 @@ describe('DataConsultService', () => {
|
||||
it('should log error when repository throws exception', async () => {
|
||||
const repositoryError = new Error('Database connection failed');
|
||||
context.mockRepository.findRegions.mockRejectedValue(repositoryError);
|
||||
await expect(context.service.getRegions()).rejects.toThrow(HttpException);
|
||||
expect(context.mockLogger.error).toHaveBeenCalledWith('Erro ao buscar regiões', repositoryError);
|
||||
await expect(context.service.getRegions()).rejects.toThrow(
|
||||
HttpException,
|
||||
);
|
||||
expect(context.mockLogger.error).toHaveBeenCalledWith(
|
||||
'Erro ao buscar regiões',
|
||||
repositoryError,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,21 +1,16 @@
|
||||
|
||||
import { ApiTags, ApiOperation, ApiParam, ApiBearerAuth, ApiResponse } from '@nestjs/swagger';
|
||||
import {
|
||||
ApiTags,
|
||||
} from '@nestjs/swagger';
|
||||
import { Controller, Get, Param } from '@nestjs/common';
|
||||
import { clientesService } from './clientes.service';
|
||||
|
||||
@ApiTags('clientes')
|
||||
@Controller('api/v1/')
|
||||
export class clientesController {
|
||||
|
||||
constructor(private readonly clientesService: clientesService) {}
|
||||
|
||||
|
||||
@Get('clientes/:filter')
|
||||
async customer(@Param('filter') filter: string) {
|
||||
return this.clientesService.customers(filter);
|
||||
}
|
||||
|
||||
|
||||
export class clientesController {
|
||||
constructor(private readonly clientesService: clientesService) {}
|
||||
|
||||
@Get('clientes/:filter')
|
||||
async customer(@Param('filter') filter: string) {
|
||||
return this.clientesService.customers(filter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable prettier/prettier */
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
|
||||
import { clientesService } from './clientes.service';
|
||||
import { clientesController } from './clientes.controller';
|
||||
|
||||
|
||||
@@ -63,7 +63,9 @@ export class clientesService {
|
||||
' ( '||REGEXP_REPLACE(PCCLIENT.CGCENT, '[^0-9]', '')||' )' as "name"
|
||||
,PCCLIENT.ESTCOB as "estcob"
|
||||
FROM PCCLIENT
|
||||
WHERE PCCLIENT.CLIENTE LIKE '${filter.toUpperCase().replace('@', '%')}%'
|
||||
WHERE PCCLIENT.CLIENTE LIKE '${filter
|
||||
.toUpperCase()
|
||||
.replace('@', '%')}%'
|
||||
ORDER BY PCCLIENT.CLIENTE`;
|
||||
customers = await queryRunner.manager.query(sql);
|
||||
}
|
||||
@@ -72,7 +74,7 @@ export class clientesService {
|
||||
} finally {
|
||||
await queryRunner.release();
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -103,7 +105,7 @@ export class clientesService {
|
||||
} finally {
|
||||
await queryRunner.release();
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -136,19 +138,13 @@ export class clientesService {
|
||||
} finally {
|
||||
await queryRunner.release();
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Limpar cache de clientes (útil para invalidação)
|
||||
* @param pattern - Padrão de chaves para limpar (opcional)
|
||||
*/
|
||||
|
||||
async clearCustomersCache(pattern?: string) {
|
||||
const cachePattern = pattern || 'clientes:*';
|
||||
|
||||
// Nota: Esta funcionalidade requer implementação específica do Redis
|
||||
// Por enquanto, mantemos a interface para futuras implementações
|
||||
console.log(`Cache de clientes seria limpo para o padrão: ${cachePattern}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,110 +1,170 @@
|
||||
import { Controller, Get, Param, Query, UseGuards, UsePipes, ValidationPipe, ParseIntPipe } from '@nestjs/common';
|
||||
import { ApiTags, ApiOperation, ApiParam, ApiBearerAuth, ApiResponse } from '@nestjs/swagger';
|
||||
import { DataConsultService } from './data-consult.service';
|
||||
import { JwtAuthGuard } from 'src/auth/guards/jwt-auth.guard';
|
||||
import { ProductDto } from './dto/product.dto';
|
||||
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 { RegionDto } from './dto/region.dto';
|
||||
import { CarrierDto, FindCarriersDto } from './dto/carrier.dto';
|
||||
|
||||
@ApiTags('DataConsult')
|
||||
@Controller('api/v1/data-consult')
|
||||
export class DataConsultController {
|
||||
constructor(private readonly dataConsultService: DataConsultService) {}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@Get('stores')
|
||||
@ApiOperation({ summary: 'Lista todas as lojas' })
|
||||
@ApiResponse({ status: 200, description: 'Lista de lojas retornada com sucesso', type: [StoreDto] })
|
||||
async stores(): Promise<StoreDto[]> {
|
||||
return this.dataConsultService.stores();
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@Get('sellers')
|
||||
@ApiOperation({ summary: 'Lista todos os vendedores' })
|
||||
@ApiResponse({ status: 200, description: 'Lista de vendedores retornada com sucesso', type: [SellerDto] })
|
||||
async sellers(): Promise<SellerDto[]> {
|
||||
return this.dataConsultService.sellers();
|
||||
}
|
||||
|
||||
@Get('billings')
|
||||
@ApiOperation({ summary: 'Retorna informações de faturamento' })
|
||||
@ApiResponse({ status: 200, description: 'Informações de faturamento retornadas com sucesso', type: [BillingDto] })
|
||||
async billings(): Promise<BillingDto[]> {
|
||||
return this.dataConsultService.billings();
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@Get('customers/:filter')
|
||||
@ApiOperation({ summary: 'Filtra clientes pelo parâmetro fornecido' })
|
||||
@ApiParam({ name: 'filter', description: 'Filtro de busca para clientes' })
|
||||
@ApiResponse({ status: 200, description: 'Lista de clientes filtrados retornada com sucesso', type: [CustomerDto] })
|
||||
async customer(@Param('filter') filter: string): Promise<CustomerDto[]> {
|
||||
return this.dataConsultService.customers(filter);
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@Get('products/:filter')
|
||||
@ApiOperation({ summary: 'Busca produtos filtrados' })
|
||||
@ApiParam({ name: 'filter', description: 'Filtro de busca' })
|
||||
@ApiResponse({ status: 200, description: 'Lista de produtos filtrados retornada com sucesso', type: [ProductDto] })
|
||||
async products(@Param('filter') filter: string): Promise<ProductDto[]> {
|
||||
return this.dataConsultService.products(filter);
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@Get('all')
|
||||
@ApiOperation({ summary: 'Lista 500 produtos' })
|
||||
@ApiResponse({ status: 200, description: 'Lista de 500 produtos retornada com sucesso', type: [ProductDto] })
|
||||
async getAllProducts(): Promise<ProductDto[]> {
|
||||
return this.dataConsultService.getAllProducts();
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@Get('carriers/all')
|
||||
@ApiOperation({ summary: 'Lista todas as transportadoras cadastradas' })
|
||||
@ApiResponse({ status: 200, description: 'Lista de transportadoras retornada com sucesso', type: [CarrierDto] })
|
||||
@UsePipes(new ValidationPipe({ transform: true }))
|
||||
async getAllCarriers(): Promise<CarrierDto[]> {
|
||||
return this.dataConsultService.getAllCarriers();
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@Get('carriers')
|
||||
@ApiOperation({ summary: 'Busca transportadoras por período de data' })
|
||||
@ApiResponse({ status: 200, description: 'Lista de transportadoras por período retornada com sucesso', type: [CarrierDto] })
|
||||
@UsePipes(new ValidationPipe({ transform: true }))
|
||||
async getCarriersByDate(@Query() query: FindCarriersDto): Promise<CarrierDto[]> {
|
||||
return this.dataConsultService.getCarriersByDate(query);
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@Get('carriers/order/:orderId')
|
||||
@ApiOperation({ summary: 'Busca transportadoras de um pedido específico' })
|
||||
@ApiParam({ name: 'orderId', example: 236001388 })
|
||||
@ApiResponse({ status: 200, description: 'Lista de transportadoras do pedido retornada com sucesso', type: [CarrierDto] })
|
||||
@UsePipes(new ValidationPipe({ transform: true }))
|
||||
async getOrderCarriers(@Param('orderId', ParseIntPipe) orderId: number): Promise<CarrierDto[]> {
|
||||
return this.dataConsultService.getOrderCarriers(orderId);
|
||||
}
|
||||
|
||||
@Get('regions')
|
||||
@ApiOperation({ summary: 'Lista todas as regiões cadastradas' })
|
||||
@ApiResponse({ status: 200, description: 'Lista de regiões retornada com sucesso', type: [RegionDto] })
|
||||
async getRegions(): Promise<RegionDto[]> {
|
||||
return this.dataConsultService.getRegions();
|
||||
}
|
||||
|
||||
}
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Param,
|
||||
Query,
|
||||
UseGuards,
|
||||
UsePipes,
|
||||
ValidationPipe,
|
||||
ParseIntPipe,
|
||||
} from '@nestjs/common';
|
||||
import {
|
||||
ApiTags,
|
||||
ApiOperation,
|
||||
ApiParam,
|
||||
ApiBearerAuth,
|
||||
ApiResponse,
|
||||
} from '@nestjs/swagger';
|
||||
import { DataConsultService } from './data-consult.service';
|
||||
import { JwtAuthGuard } from 'src/auth/guards/jwt-auth.guard';
|
||||
import { ProductDto } from './dto/product.dto';
|
||||
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 { RegionDto } from './dto/region.dto';
|
||||
import { CarrierDto, FindCarriersDto } from './dto/carrier.dto';
|
||||
|
||||
@ApiTags('DataConsult')
|
||||
@Controller('api/v1/data-consult')
|
||||
export class DataConsultController {
|
||||
constructor(private readonly dataConsultService: DataConsultService) {}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@Get('stores')
|
||||
@ApiOperation({ summary: 'Lista todas as lojas' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Lista de lojas retornada com sucesso',
|
||||
type: [StoreDto],
|
||||
})
|
||||
async stores(): Promise<StoreDto[]> {
|
||||
return this.dataConsultService.stores();
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@Get('sellers')
|
||||
@ApiOperation({ summary: 'Lista todos os vendedores' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Lista de vendedores retornada com sucesso',
|
||||
type: [SellerDto],
|
||||
})
|
||||
async sellers(): Promise<SellerDto[]> {
|
||||
return this.dataConsultService.sellers();
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@Get('billings')
|
||||
@ApiOperation({ summary: 'Retorna informações de faturamento' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Informações de faturamento retornadas com sucesso',
|
||||
type: [BillingDto],
|
||||
})
|
||||
async billings(): Promise<BillingDto[]> {
|
||||
return this.dataConsultService.billings();
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@Get('customers/:filter')
|
||||
@ApiOperation({ summary: 'Filtra clientes pelo parâmetro fornecido' })
|
||||
@ApiParam({ name: 'filter', description: 'Filtro de busca para clientes' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Lista de clientes filtrados retornada com sucesso',
|
||||
type: [CustomerDto],
|
||||
})
|
||||
async customer(@Param('filter') filter: string): Promise<CustomerDto[]> {
|
||||
return this.dataConsultService.customers(filter);
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@Get('products/:filter')
|
||||
@ApiOperation({ summary: 'Busca produtos filtrados' })
|
||||
@ApiParam({ name: 'filter', description: 'Filtro de busca' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Lista de produtos filtrados retornada com sucesso',
|
||||
type: [ProductDto],
|
||||
})
|
||||
async products(@Param('filter') filter: string): Promise<ProductDto[]> {
|
||||
return this.dataConsultService.products(filter);
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@Get('all')
|
||||
@ApiOperation({ summary: 'Lista 500 produtos' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Lista de 500 produtos retornada com sucesso',
|
||||
type: [ProductDto],
|
||||
})
|
||||
async getAllProducts(): Promise<ProductDto[]> {
|
||||
return this.dataConsultService.getAllProducts();
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@Get('carriers/all')
|
||||
@ApiOperation({ summary: 'Lista todas as transportadoras cadastradas' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Lista de transportadoras retornada com sucesso',
|
||||
type: [CarrierDto],
|
||||
})
|
||||
@UsePipes(new ValidationPipe({ transform: true }))
|
||||
async getAllCarriers(): Promise<CarrierDto[]> {
|
||||
return this.dataConsultService.getAllCarriers();
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@Get('carriers')
|
||||
@ApiOperation({ summary: 'Busca transportadoras por período de data' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Lista de transportadoras por período retornada com sucesso',
|
||||
type: [CarrierDto],
|
||||
})
|
||||
@UsePipes(new ValidationPipe({ transform: true }))
|
||||
async getCarriersByDate(
|
||||
@Query() query: FindCarriersDto,
|
||||
): Promise<CarrierDto[]> {
|
||||
return this.dataConsultService.getCarriersByDate(query);
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@Get('carriers/order/:orderId')
|
||||
@ApiOperation({ summary: 'Busca transportadoras de um pedido específico' })
|
||||
@ApiParam({ name: 'orderId', example: 236001388 })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Lista de transportadoras do pedido retornada com sucesso',
|
||||
type: [CarrierDto],
|
||||
})
|
||||
@UsePipes(new ValidationPipe({ transform: true }))
|
||||
async getOrderCarriers(
|
||||
@Param('orderId', ParseIntPipe) orderId: number,
|
||||
): Promise<CarrierDto[]> {
|
||||
return this.dataConsultService.getOrderCarriers(orderId);
|
||||
}
|
||||
|
||||
@Get('regions')
|
||||
@ApiOperation({ summary: 'Lista todas as regiões cadastradas' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Lista de regiões retornada com sucesso',
|
||||
type: [RegionDto],
|
||||
})
|
||||
async getRegions(): Promise<RegionDto[]> {
|
||||
return this.dataConsultService.getRegions();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,14 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { DataConsultService } from './data-consult.service';
|
||||
import { DataConsultController } from './data-consult.controller';
|
||||
import { DataConsultRepository } from './data-consult.repository';
|
||||
import { LoggerModule } from 'src/Log/logger.module';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
import { RedisModule } from 'src/core/configs/cache/redis.module';
|
||||
import { clientes } from './clientes.module';
|
||||
|
||||
@Module({
|
||||
imports: [LoggerModule, ConfigModule, RedisModule, clientes],
|
||||
controllers: [DataConsultController],
|
||||
providers: [
|
||||
DataConsultService,
|
||||
DataConsultRepository,
|
||||
|
||||
],
|
||||
})
|
||||
export class DataConsultModule {}
|
||||
import { Module } from '@nestjs/common';
|
||||
import { DataConsultService } from './data-consult.service';
|
||||
import { DataConsultController } from './data-consult.controller';
|
||||
import { DataConsultRepository } from './data-consult.repository';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
import { RedisModule } from 'src/core/configs/cache/redis.module';
|
||||
import { clientes } from './clientes.module';
|
||||
|
||||
@Module({
|
||||
imports: [ConfigModule, RedisModule, clientes],
|
||||
controllers: [DataConsultController],
|
||||
providers: [DataConsultService, DataConsultRepository],
|
||||
})
|
||||
export class DataConsultModule {}
|
||||
|
||||
@@ -1,331 +1,435 @@
|
||||
import { Injectable, HttpException, HttpStatus, Inject } 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 { ILogger } from '../Log/ILogger';
|
||||
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 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('LoggerService') private readonly logger: ILogger,
|
||||
@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 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
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 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,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,26 +4,26 @@ import { IsOptional, IsString, IsDateString } from 'class-validator';
|
||||
export class CarrierDto {
|
||||
@ApiProperty({
|
||||
description: 'ID da transportadora',
|
||||
example: '123'
|
||||
example: '123',
|
||||
})
|
||||
carrierId: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'Nome da transportadora',
|
||||
example: 'TRANSPORTADORA ABC LTDA'
|
||||
example: 'TRANSPORTADORA ABC LTDA',
|
||||
})
|
||||
carrierName: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'Descrição completa da transportadora (ID - Nome)',
|
||||
example: '123 - TRANSPORTADORA ABC LTDA'
|
||||
example: '123 - TRANSPORTADORA ABC LTDA',
|
||||
})
|
||||
carrierDescription: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'Quantidade de pedidos da transportadora no período',
|
||||
example: 15,
|
||||
required: false
|
||||
required: false,
|
||||
})
|
||||
ordersCount?: number;
|
||||
}
|
||||
@@ -32,7 +32,7 @@ export class FindCarriersDto {
|
||||
@ApiProperty({
|
||||
description: 'Data inicial para filtro (formato YYYY-MM-DD)',
|
||||
example: '2024-01-01',
|
||||
required: false
|
||||
required: false,
|
||||
})
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
@@ -41,7 +41,7 @@ export class FindCarriersDto {
|
||||
@ApiProperty({
|
||||
description: 'Data final para filtro (formato YYYY-MM-DD)',
|
||||
example: '2024-12-31',
|
||||
required: false
|
||||
required: false,
|
||||
})
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
@@ -50,9 +50,9 @@ export class FindCarriersDto {
|
||||
@ApiProperty({
|
||||
description: 'ID da filial',
|
||||
example: '1',
|
||||
required: false
|
||||
required: false,
|
||||
})
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
codfilial?: string;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,4 +20,3 @@ export class RegionDto {
|
||||
Object.assign(this, partial);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user