diff --git a/eslint.config.js b/eslint.config.js index eb08d94..ab043a2 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -18,6 +18,13 @@ module.exports = [ globals: { node: true, jest: true, + process: 'readonly', + console: 'readonly', + __dirname: 'readonly', + __filename: 'readonly', + require: 'readonly', + module: 'readonly', + exports: 'readonly', describe: 'readonly', it: 'readonly', test: 'readonly', @@ -26,6 +33,7 @@ module.exports = [ afterEach: 'readonly', beforeAll: 'readonly', afterAll: 'readonly', + fail: 'readonly', }, }, plugins: { @@ -38,6 +46,17 @@ module.exports = [ '@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off', '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-require-imports': 'warn', + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + }, + ], + 'no-useless-escape': 'warn', + 'no-import-assign': 'off', 'prettier/prettier': 'error', }, }, @@ -54,8 +73,37 @@ module.exports = [ beforeAll: 'readonly', afterAll: 'readonly', jest: 'readonly', + fail: 'readonly', + require: 'readonly', }, }, + rules: { + '@typescript-eslint/no-require-imports': 'off', + }, + }, + { + files: ['**/*.js'], + languageOptions: { + globals: { + node: true, + jest: true, + process: 'readonly', + console: 'readonly', + __dirname: 'readonly', + __filename: 'readonly', + require: 'readonly', + module: 'readonly', + exports: 'readonly', + global: 'readonly', + Buffer: 'readonly', + }, + ecmaVersion: 'latest', + sourceType: 'commonjs', + }, + rules: { + 'no-undef': 'off', + '@typescript-eslint/no-require-imports': 'off', + }, }, { ignores: ['dist/**', 'node_modules/**', 'coverage/**'], diff --git a/src/app.module.ts b/src/app.module.ts index 3752ee4..a1fdb6d 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -4,14 +4,11 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { createOracleConfig } from './core/configs/typeorm.oracle.config'; import { createPostgresConfig } from './core/configs/typeorm.postgres.config'; import { LogisticModule } from './logistic/logistic.module'; -import { OrdersPaymentModule } from './orders-payment/orders-payment.module'; import { AuthModule } from './auth/auth/auth.module'; import { DataConsultModule } from './data-consult/data-consult.module'; import { OrdersModule } from './orders/modules/orders.module'; import { HttpModule } from '@nestjs/axios'; import { DebModule } from './orders/modules/deb.module'; -import { LogisticController } from './logistic/logistic.controller'; -import { LogisticService } from './logistic/logistic.service'; import jwtConfig from './auth/jwt.config'; import { UsersModule } from './auth/users/users.module'; import { ProductsModule } from './products/products.module'; @@ -48,7 +45,6 @@ import { PartnersModule } from './partners/partners.module'; }), }), LogisticModule, - OrdersPaymentModule, HttpModule, OrdersModule, clientes, @@ -56,11 +52,8 @@ import { PartnersModule } from './partners/partners.module'; DataConsultModule, AuthModule, DebModule, - OrdersModule, PartnersModule, ], - controllers: [LogisticController], - providers: [LogisticService], }) export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { diff --git a/src/auth/auth/auth.controller.ts b/src/auth/auth/auth.controller.ts index a2db478..819c6d7 100644 --- a/src/auth/auth/auth.controller.ts +++ b/src/auth/auth/auth.controller.ts @@ -12,7 +12,6 @@ import { Query, } from '@nestjs/common'; import { CommandBus } from '@nestjs/cqrs'; -import { CqrsModule } from '@nestjs/cqrs'; import { AuthenticateUserCommand } from './commands/authenticate-user.command'; import { LoginResponseDto } from './dto/LoginResponseDto'; import { LoginDto } from './dto/login.dto'; diff --git a/src/auth/auth/auth.service.ts b/src/auth/auth/auth.service.ts index 7b93696..fbc0a9a 100644 --- a/src/auth/auth/auth.service.ts +++ b/src/auth/auth/auth.service.ts @@ -63,11 +63,7 @@ export class AuthService { throw new BadRequestException('ID de usuário inválido'); } - if ( - sellerId !== null && - sellerId !== undefined && - sellerId < 0 - ) { + if (sellerId !== null && sellerId !== undefined && sellerId < 0) { throw new BadRequestException('ID de vendedor inválido'); } @@ -299,7 +295,7 @@ export class AuthService { let decoded: JwtPayload | null = null; try { decoded = this.jwtService.decode(token) as JwtPayload; - } catch (error) { + } catch (_error) { throw new BadRequestException( 'Token inválido ou não pode ser decodificado', ); diff --git a/src/auth/guards/__tests__/rate-limiting.guard.spec.ts b/src/auth/guards/__tests__/rate-limiting.guard.spec.ts index a79e8b7..8daaba5 100644 --- a/src/auth/guards/__tests__/rate-limiting.guard.spec.ts +++ b/src/auth/guards/__tests__/rate-limiting.guard.spec.ts @@ -5,7 +5,7 @@ import { RateLimitingService } from '../../services/rate-limiting.service'; describe('RateLimitingGuard - Tests that expose problems', () => { let guard: RateLimitingGuard; - let rateLimitingService: RateLimitingService; + let _rateLimitingService: RateLimitingService; let mockExecutionContext: ExecutionContext; let mockGetRequest: jest.Mock; @@ -27,7 +27,7 @@ describe('RateLimitingGuard - Tests that expose problems', () => { }).compile(); guard = module.get(RateLimitingGuard); - rateLimitingService = module.get(RateLimitingService); + _rateLimitingService = module.get(RateLimitingService); mockGetRequest = jest.fn().mockReturnValue({ headers: {}, diff --git a/src/auth/models/jwt-payload.model.ts b/src/auth/models/jwt-payload.model.ts index b3c5a7a..f636df0 100644 --- a/src/auth/models/jwt-payload.model.ts +++ b/src/auth/models/jwt-payload.model.ts @@ -1,4 +1,3 @@ -/* eslint-disable prettier/prettier */ export interface JwtPayload { id: number; sellerId: number | null; @@ -8,4 +7,3 @@ export interface JwtPayload { exp?: number; // Timestamp de expiração do JWT sessionId?: string; // ID da sessão atual } - diff --git a/src/auth/services/__tests__/refresh-token.service.spec.helper.ts b/src/auth/services/__tests__/refresh-token.service.spec.helper.ts index f488420..ed1f8cd 100644 --- a/src/auth/services/__tests__/refresh-token.service.spec.helper.ts +++ b/src/auth/services/__tests__/refresh-token.service.spec.helper.ts @@ -61,4 +61,3 @@ export async function createRefreshTokenServiceTestModule( mockJwtService, }; } - diff --git a/src/auth/services/__tests__/refresh-token.service.spec.ts b/src/auth/services/__tests__/refresh-token.service.spec.ts index 9c2340e..98bfc3c 100644 --- a/src/auth/services/__tests__/refresh-token.service.spec.ts +++ b/src/auth/services/__tests__/refresh-token.service.spec.ts @@ -389,4 +389,3 @@ describe('RefreshTokenService', () => { }); }); }); - diff --git a/src/auth/services/__tests__/token-blacklist.service.spec.helper.ts b/src/auth/services/__tests__/token-blacklist.service.spec.helper.ts index c0bf006..cdc4acf 100644 --- a/src/auth/services/__tests__/token-blacklist.service.spec.helper.ts +++ b/src/auth/services/__tests__/token-blacklist.service.spec.helper.ts @@ -59,4 +59,3 @@ export async function createTokenBlacklistServiceTestModule( mockJwtService, }; } - diff --git a/src/auth/services/__tests__/token-blacklist.service.spec.ts b/src/auth/services/__tests__/token-blacklist.service.spec.ts index db95702..71d61d1 100644 --- a/src/auth/services/__tests__/token-blacklist.service.spec.ts +++ b/src/auth/services/__tests__/token-blacklist.service.spec.ts @@ -90,9 +90,9 @@ describe('TokenBlacklistService', () => { context.mockJwtService.decode.mockReturnValue(null); - await expect( - context.service.addToBlacklist(mockToken), - ).rejects.toThrow('Token inválido'); + await expect(context.service.addToBlacklist(mockToken)).rejects.toThrow( + 'Token inválido', + ); }); it('deve lançar erro quando decode falha', async () => { @@ -102,9 +102,9 @@ describe('TokenBlacklistService', () => { throw new Error('Token malformado'); }); - await expect( - context.service.addToBlacklist(mockToken), - ).rejects.toThrow('Erro ao adicionar token à blacklist'); + await expect(context.service.addToBlacklist(mockToken)).rejects.toThrow( + 'Erro ao adicionar token à blacklist', + ); }); }); @@ -169,9 +169,7 @@ describe('TokenBlacklistService', () => { }; context.mockJwtService.decode.mockReturnValue(mockPayload); - context.mockRedisClient.get.mockRejectedValue( - new Error('Redis error'), - ); + context.mockRedisClient.get.mockRejectedValue(new Error('Redis error')); const result = await context.service.isBlacklisted(mockToken); @@ -254,4 +252,3 @@ describe('TokenBlacklistService', () => { }); }); }); - diff --git a/src/auth/services/login-audit.service.ts b/src/auth/services/login-audit.service.ts index e060869..4dd0756 100644 --- a/src/auth/services/login-audit.service.ts +++ b/src/auth/services/login-audit.service.ts @@ -193,7 +193,6 @@ export class LoginAuditService { const cutoffDate = new Date( DateUtil.nowTimestamp() - 30 * 24 * 60 * 60 * 1000, ); - const cutoffDateStr = DateUtil.toBrazilString(cutoffDate, 'yyyy-MM-dd'); const oldDates = this.getDateRange(new Date('2020-01-01'), cutoffDate); for (const date of oldDates) { diff --git a/src/auth/services/rate-limiting.service.ts b/src/auth/services/rate-limiting.service.ts index dc8ff22..f34bff1 100644 --- a/src/auth/services/rate-limiting.service.ts +++ b/src/auth/services/rate-limiting.service.ts @@ -62,16 +62,15 @@ export class RateLimitingService { finalConfig.blockDurationMs, )) as [number, number]; - const [attempts, isBlockedResult] = result; + const [_attempts, isBlockedResult] = result; return isBlockedResult === 0; } async recordAttempt( ip: string, success: boolean, - config?: Partial, + _config?: Partial, ): Promise { - const finalConfig = { ...this.defaultConfig, ...config }; const key = this.buildAttemptKey(ip); const blockKey = this.buildBlockKey(ip); diff --git a/src/auth/services/refresh-token.service.ts b/src/auth/services/refresh-token.service.ts index 017179d..92743df 100644 --- a/src/auth/services/refresh-token.service.ts +++ b/src/auth/services/refresh-token.service.ts @@ -80,7 +80,7 @@ export class RefreshTokenService { sessionId: sessionId || tokenData.sessionId, tokenId, } as JwtPayload; - } catch (error) { + } catch (_error) { throw new UnauthorizedException('Refresh token inválido'); } } diff --git a/src/auth/services/token-blacklist.service.ts b/src/auth/services/token-blacklist.service.ts index de6fb7b..42d60cf 100644 --- a/src/auth/services/token-blacklist.service.ts +++ b/src/auth/services/token-blacklist.service.ts @@ -32,7 +32,7 @@ export class TokenBlacklistService { const blacklistKey = this.buildBlacklistKey(token); const result = await this.redis.get(blacklistKey); return result === 'blacklisted'; - } catch (error) { + } catch (_error) { return false; } } diff --git a/src/auth/strategies/jwt-strategy.spec.ts b/src/auth/strategies/jwt-strategy.spec.ts index 3189d7e..5611036 100644 --- a/src/auth/strategies/jwt-strategy.spec.ts +++ b/src/auth/strategies/jwt-strategy.spec.ts @@ -61,7 +61,7 @@ describe('JwtStrategy', () => { * - Lançar UnauthorizedException * - Com mensagem 'Payload inválido ou incompleto' */ - testCases.forEach(({ payload, description }) => { + testCases.forEach(({ payload, description: _description }) => { expect(() => { if (!payload.id || !payload.sessionId) { throw new UnauthorizedException('Payload inválido ou incompleto'); diff --git a/src/auth/users/email.service.ts b/src/auth/users/email.service.ts index 4059496..d599ae0 100644 --- a/src/auth/users/email.service.ts +++ b/src/auth/users/email.service.ts @@ -3,15 +3,16 @@ import { Injectable } from '@nestjs/common'; @Injectable() export class EmailService { async sendPasswordReset(email: string, newPassword: string) { - const sql = ` - INSERT INTO CORRESPONDENCIAS ( - CORRESPONDENCIA_ID, DTINCLUSAO, TITULO, MENSAGEM, EMAIL, DESTINATARIO - ) VALUES ( - SEQ_CORRESPONDENCIAS.NEXTVAL, SYSDATE, 'Alteração de senha - CoteLivia', - 'Sua nova senha para acesso ao portal COTELIVIA é ${newPassword}', - :email, :email - ) - `; + // SQL query would be executed here if database connection was available + // const sql = ` + // INSERT INTO CORRESPONDENCIAS ( + // CORRESPONDENCIA_ID, DTINCLUSAO, TITULO, MENSAGEM, EMAIL, DESTINATARIO + // ) VALUES ( + // SEQ_CORRESPONDENCIAS.NEXTVAL, SYSDATE, 'Alteração de senha - CoteLivia', + // 'Sua nova senha para acesso ao portal COTELIVIA é ${newPassword}', + // :email, :email + // ) + // `; console.log(`[Email enviado para ${email}] Senha: ${newPassword}`); } diff --git a/src/common/validators/sanitize.validator.ts b/src/common/validators/sanitize.validator.ts index 249fe76..3352d3e 100644 --- a/src/common/validators/sanitize.validator.ts +++ b/src/common/validators/sanitize.validator.ts @@ -13,7 +13,7 @@ export function IsSanitized(validationOptions?: ValidationOptions) { propertyName: propertyName, options: validationOptions, validator: { - validate(value: any, args: ValidationArguments) { + validate(value: any, _args: ValidationArguments) { if (typeof value !== 'string') return true; // Skip non-string values const sqlInjectionRegex = @@ -24,7 +24,7 @@ export function IsSanitized(validationOptions?: ValidationOptions) { // Check for NoSQL injection patterns (MongoDB) const noSqlInjectionRegex = - /(\$where|\$ne|\$gt|\$lt|\$gte|\$lte|\$in|\$nin|\$or|\$and|\$regex|\$options|\$elemMatch|\{.*\:.*\})/i; + /(\$where|\$ne|\$gt|\$lt|\$gte|\$lte|\$in|\$nin|\$or|\$and|\$regex|\$options|\$elemMatch|\{.*:.*\})/i; if (noSqlInjectionRegex.test(value)) { return false; } @@ -38,7 +38,7 @@ export function IsSanitized(validationOptions?: ValidationOptions) { return true; }, - defaultMessage(args: ValidationArguments) { + defaultMessage(_args: ValidationArguments) { return 'A entrada contém caracteres inválidos ou padrões potencialmente maliciosos'; }, }, @@ -55,7 +55,7 @@ export function IsSecureId(validationOptions?: ValidationOptions) { propertyName: propertyName, options: validationOptions, validator: { - validate(value: any, args: ValidationArguments) { + validate(value: any, _args: ValidationArguments) { if (typeof value !== 'string' && typeof value !== 'number') return false; @@ -69,7 +69,7 @@ export function IsSecureId(validationOptions?: ValidationOptions) { // Se for número, deve ser positivo return value > 0; }, - defaultMessage(args: ValidationArguments) { + defaultMessage(_args: ValidationArguments) { return 'O ID fornecido não é seguro ou está em formato inválido'; }, }, diff --git a/src/core/configs/cache/redis-client.adapter.ts b/src/core/configs/cache/redis-client.adapter.ts index 2218ec2..c3dd1c7 100644 --- a/src/core/configs/cache/redis-client.adapter.ts +++ b/src/core/configs/cache/redis-client.adapter.ts @@ -15,7 +15,7 @@ export class RedisClientAdapter implements IRedisClient { try { return JSON.parse(data); - } catch (error) { + } catch (_error) { // If it's not valid JSON, return the raw string value return data as T; } diff --git a/src/core/models/change-password.model.ts b/src/core/models/change-password.model.ts index bb20508..7d1568f 100644 --- a/src/core/models/change-password.model.ts +++ b/src/core/models/change-password.model.ts @@ -1,6 +1,5 @@ -/* eslint-disable prettier/prettier */ -export class ChangePasswordModel { - id: number; - password: string; - newPassword: string; - } \ No newline at end of file +export class ChangePasswordModel { + id: number; + password: string; + newPassword: string; +} diff --git a/src/core/models/exposed-product.model.ts b/src/core/models/exposed-product.model.ts index 92b2203..0f1ee4d 100644 --- a/src/core/models/exposed-product.model.ts +++ b/src/core/models/exposed-product.model.ts @@ -1,6 +1,5 @@ -/* eslint-disable prettier/prettier */ -export class ExposedProduct { - ean: string; - storeId: string; - userId: number; -} \ No newline at end of file +export class ExposedProduct { + ean: string; + storeId: string; + userId: number; +} diff --git a/src/core/models/reset-password.model.ts b/src/core/models/reset-password.model.ts index e3f0b50..1c09b5d 100644 --- a/src/core/models/reset-password.model.ts +++ b/src/core/models/reset-password.model.ts @@ -1,5 +1,4 @@ -/* eslint-disable prettier/prettier */ -export class ResetPasswordModel { - document: string; - email: string; -} +export class ResetPasswordModel { + document: string; + email: string; +} diff --git a/src/core/models/result.model.ts b/src/core/models/result.model.ts index 29401e8..048edf5 100644 --- a/src/core/models/result.model.ts +++ b/src/core/models/result.model.ts @@ -1,9 +1,8 @@ -/* eslint-disable prettier/prettier */ export class ResultModel { - - constructor( - public success: boolean, - public message: string, - public data: any, - public errors: any) {}; + constructor( + public success: boolean, + public message: string, + public data: any, + public errors: any, + ) {} } diff --git a/src/data-consult/__tests__/data-consult.service.spec.helper.ts b/src/data-consult/__tests__/data-consult.service.spec.helper.ts index db01af0..41824b2 100644 --- a/src/data-consult/__tests__/data-consult.service.spec.helper.ts +++ b/src/data-consult/__tests__/data-consult.service.spec.helper.ts @@ -74,11 +74,11 @@ export async function createDataConsultServiceTestModule( error: jest.fn(), }; - jest.spyOn(Logger.prototype, 'error').mockImplementation( - (message: any, ...optionalParams: any[]) => { + jest + .spyOn(Logger.prototype, 'error') + .mockImplementation((message: any, ...optionalParams: any[]) => { mockLogger.error(message, ...optionalParams); - }, - ); + }); return { service, diff --git a/src/data-consult/__tests__/data-consult.service.spec.ts b/src/data-consult/__tests__/data-consult.service.spec.ts index 9257882..5111ac1 100644 --- a/src/data-consult/__tests__/data-consult.service.spec.ts +++ b/src/data-consult/__tests__/data-consult.service.spec.ts @@ -623,15 +623,15 @@ describe('DataConsultService', () => { }); it('should throw error when filter is invalid', async () => { - await expect( - context.service.products(null as any), - ).rejects.toThrow(HttpException); + await expect(context.service.products(null as any)).rejects.toThrow( + HttpException, + ); await expect( context.service.products(undefined as any), ).rejects.toThrow(HttpException); - await expect( - context.service.products('' as any), - ).rejects.toThrow(HttpException); + await expect(context.service.products('' as any)).rejects.toThrow( + HttpException, + ); }); it('should log error when repository throws exception', async () => { diff --git a/src/data-consult/clientes.controller.ts b/src/data-consult/clientes.controller.ts index a147b56..b6c7145 100644 --- a/src/data-consult/clientes.controller.ts +++ b/src/data-consult/clientes.controller.ts @@ -1,6 +1,4 @@ -import { - ApiTags, -} from '@nestjs/swagger'; +import { ApiTags } from '@nestjs/swagger'; import { Controller, Get, Param } from '@nestjs/common'; import { clientesService } from './clientes.service'; diff --git a/src/data-consult/clientes.module.ts b/src/data-consult/clientes.module.ts index d7010ae..bc35502 100644 --- a/src/data-consult/clientes.module.ts +++ b/src/data-consult/clientes.module.ts @@ -1,5 +1,3 @@ -/* eslint-disable prettier/prettier */ - import { clientesService } from './clientes.service'; import { clientesController } from './clientes.controller'; @@ -10,10 +8,8 @@ https://docs.nestjs.com/modules import { Module } from '@nestjs/common'; @Module({ - imports: [], - controllers: [ - clientesController,], - providers: [ - clientesService,], + imports: [], + controllers: [clientesController], + providers: [clientesService], }) -export class clientes { } +export class clientes {} diff --git a/src/data-consult/clientes.service.ts b/src/data-consult/clientes.service.ts index 9daaa02..ba6e491 100644 --- a/src/data-consult/clientes.service.ts +++ b/src/data-consult/clientes.service.ts @@ -142,9 +142,7 @@ export class clientesService { ); } - - async clearCustomersCache(pattern?: string) { - const cachePattern = pattern || 'clientes:*'; - + async clearCustomersCache(_pattern?: string) { + // Cache clearing logic would be implemented here } } diff --git a/src/data-consult/data-consult.controller.ts b/src/data-consult/data-consult.controller.ts index c9d1487..300f349 100644 --- a/src/data-consult/data-consult.controller.ts +++ b/src/data-consult/data-consult.controller.ts @@ -87,13 +87,18 @@ export class DataConsultController { @ApiBearerAuth() @Get('products/codauxiliar/:codauxiliar') @ApiOperation({ summary: 'Busca produtos por código auxiliar (EAN)' }) - @ApiParam({ name: 'codauxiliar', description: 'Código auxiliar (EAN) do produto' }) + @ApiParam({ + name: 'codauxiliar', + description: 'Código auxiliar (EAN) do produto', + }) @ApiResponse({ status: 200, description: 'Lista de produtos encontrados por código auxiliar', type: [ProductDto], }) - async productsByCodauxiliar(@Param('codauxiliar') codauxiliar: string): Promise { + async productsByCodauxiliar( + @Param('codauxiliar') codauxiliar: string, + ): Promise { return this.dataConsultService.productsByCodauxiliar(codauxiliar); } diff --git a/src/data-consult/data-consult.repository.ts b/src/data-consult/data-consult.repository.ts index 3cd28b5..7be7d28 100644 --- a/src/data-consult/data-consult.repository.ts +++ b/src/data-consult/data-consult.repository.ts @@ -124,7 +124,10 @@ export class DataConsultRepository { WHERE PCPRODUT.CODPROD = :0 OR REGEXP_REPLACE(PCPRODUT.CODAUXILIAR, '[^0-9]', '') = :1 `; - const results = await this.executeQuery(sql, [filter, cleanedFilter]); + const results = await this.executeQuery(sql, [ + filter, + cleanedFilter, + ]); return results.map((result) => new ProductDto(result)); } diff --git a/src/data-consult/data-consult.service.ts b/src/data-consult/data-consult.service.ts index 12d609b..ac8674c 100644 --- a/src/data-consult/data-consult.service.ts +++ b/src/data-consult/data-consult.service.ts @@ -1,4 +1,10 @@ -import { Injectable, HttpException, HttpStatus, Inject, Logger } from '@nestjs/common'; +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'; @@ -231,9 +237,14 @@ export class DataConsultService { 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); + throw new HttpException( + 'Código auxiliar inválido', + HttpStatus.BAD_REQUEST, + ); } - const products = await this.repository.findProductsByCodauxiliar(codauxiliar); + 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); diff --git a/src/logistic/logistic.controller.ts b/src/logistic/logistic.controller.ts index 16f895e..12ec560 100644 --- a/src/logistic/logistic.controller.ts +++ b/src/logistic/logistic.controller.ts @@ -1,65 +1,54 @@ -/* eslint-disable prettier/prettier */ - -/* -https://docs.nestjs.com/controllers#controllers -*/ - -import { LogisticService } from './logistic.service'; -import { CarOutDelivery } from '../core/models/car-out-delivery.model'; -import { CarInDelivery } from '../core/models/car-in-delivery.model'; -import { - Body, - Controller, - Get, - Param, - Post, - UseGuards - } from '@nestjs/common'; - import { JwtAuthGuard } from 'src/auth/guards/jwt-auth.guard'; - import { ApiBearerAuth, ApiTags, ApiOperation } from '@nestjs/swagger'; - - - @ApiTags('Logística') - @ApiBearerAuth() - @UseGuards(JwtAuthGuard) - @Controller('api/v1/logistic') - export class LogisticController { - constructor(private readonly logisticService: LogisticService) {} - - @Get('expedicao') - @ApiOperation({ summary: 'Retorna informações de expedição' }) - getExpedicao() { - return this.logisticService.getExpedicao(); - } - - @Get('employee') - @ApiOperation({ summary: 'Retorna lista de funcionários' }) - getEmployee() { - return this.logisticService.getEmployee(); - } - - @Get('deliveries/:placa') - @ApiOperation({ summary: 'Retorna entregas por placa' }) - getDelivery(@Param('placa') placa: string) { - return this.logisticService.getDeliveries(placa); - } - - @Get('status-car/:placa') - @ApiOperation({ summary: 'Retorna status do veículo por placa' }) - getStatusCar(@Param('placa') placa: string) { - return this.logisticService.getStatusCar(placa); - } - - @Post('create') - @ApiOperation({ summary: 'Registra saída de veículo' }) - createOutCar(@Body() data: CarOutDelivery) { - return this.logisticService.createCarOut(data); - } - - @Post('return-car') - @ApiOperation({ summary: 'Registra retorno de veículo' }) - createinCar(@Body() data: CarInDelivery) { - return this.logisticService.createCarIn(data); - } - } - \ No newline at end of file +/* +https://docs.nestjs.com/controllers#controllers +*/ + +import { LogisticService } from './logistic.service'; +import { CarOutDelivery } from '../core/models/car-out-delivery.model'; +import { CarInDelivery } from '../core/models/car-in-delivery.model'; +import { Body, Controller, Get, Param, Post, UseGuards } from '@nestjs/common'; +import { JwtAuthGuard } from 'src/auth/guards/jwt-auth.guard'; +import { ApiBearerAuth, ApiTags, ApiOperation } from '@nestjs/swagger'; + +@ApiTags('Logística') +@ApiBearerAuth() +@UseGuards(JwtAuthGuard) +@Controller('api/v1/logistic') +export class LogisticController { + constructor(private readonly logisticService: LogisticService) {} + + @Get('expedicao') + @ApiOperation({ summary: 'Retorna informações de expedição' }) + getExpedicao() { + return this.logisticService.getExpedicao(); + } + + @Get('employee') + @ApiOperation({ summary: 'Retorna lista de funcionários' }) + getEmployee() { + return this.logisticService.getEmployee(); + } + + @Get('deliveries/:placa') + @ApiOperation({ summary: 'Retorna entregas por placa' }) + getDelivery(@Param('placa') placa: string) { + return this.logisticService.getDeliveries(placa); + } + + @Get('status-car/:placa') + @ApiOperation({ summary: 'Retorna status do veículo por placa' }) + getStatusCar(@Param('placa') placa: string) { + return this.logisticService.getStatusCar(placa); + } + + @Post('create') + @ApiOperation({ summary: 'Registra saída de veículo' }) + createOutCar(@Body() data: CarOutDelivery) { + return this.logisticService.createCarOut(data); + } + + @Post('return-car') + @ApiOperation({ summary: 'Registra retorno de veículo' }) + createinCar(@Body() data: CarInDelivery) { + return this.logisticService.createCarIn(data); + } +} diff --git a/src/logistic/logistic.module.ts b/src/logistic/logistic.module.ts index bbe05f9..bc758fd 100644 --- a/src/logistic/logistic.module.ts +++ b/src/logistic/logistic.module.ts @@ -1,15 +1,10 @@ -/* eslint-disable prettier/prettier */ - - -import { LogisticController } from './logistic.controller'; -import { LogisticService } from './logistic.service'; -import { Module } from '@nestjs/common'; - -@Module({ - imports: [], - controllers: [ - LogisticController,], - providers: [ - LogisticService,], -}) -export class LogisticModule { } +import { LogisticController } from './logistic.controller'; +import { LogisticService } from './logistic.service'; +import { Module } from '@nestjs/common'; + +@Module({ + imports: [], + controllers: [LogisticController], + providers: [LogisticService], +}) +export class LogisticModule {} diff --git a/src/logistic/logistic.service.ts b/src/logistic/logistic.service.ts index 9639059..0e7644c 100644 --- a/src/logistic/logistic.service.ts +++ b/src/logistic/logistic.service.ts @@ -1,8 +1,4 @@ -import { - HttpException, - HttpStatus, - Injectable, -} from '@nestjs/common'; +import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; import { createOracleConfig } from '../core/configs/typeorm.oracle.config'; import { createPostgresConfig } from '../core/configs/typeorm.postgres.config'; import { CarOutDelivery } from '../core/models/car-out-delivery.model'; @@ -55,7 +51,7 @@ export class LogisticService { where dados.data_saida >= current_date ORDER BY dados.data_saida desc `; - const sql = `SELECT COUNT(DISTINCT PCCARREG.NUMCAR) as "qtde" + const _sql = `SELECT COUNT(DISTINCT PCCARREG.NUMCAR) as "qtde" ,SUM(PCPEDI.QT * PCPRODUT.PESOBRUTO) as "totalKG" ,SUM(CASE WHEN PCPEDC.DTINICIALSEP IS NULL THEN PCPEDI.QT ELSE 0 END * PCPRODUT.PESOBRUTO) as "total_nao_iniciado" ,SUM(CASE WHEN PCPEDC.DTINICIALSEP IS NOT NULL @@ -103,7 +99,7 @@ export class LogisticService { } } - async getDeliveries(placa: string) { + async getDeliveries(_placa: string) { const dataSource = new DataSource(createOracleConfig(this.configService)); await dataSource.initialize(); const queryRunner = dataSource.createQueryRunner(); @@ -202,10 +198,10 @@ export class LogisticService { let helperId1 = 0; let helperId2 = 0; let helperId3 = 0; - const image1 = ''; - const image2 = ''; - const image3 = ''; - const image4 = ''; + const _image1 = ''; + const _image2 = ''; + const _image3 = ''; + const _image4 = ''; data.helpers.forEach((helper) => { switch (i) { @@ -283,11 +279,11 @@ export class LogisticService { ); } - const i = 0; - const image1 = ''; - const image2 = ''; - const image3 = ''; - const image4 = ''; + const _i = 0; + const _image1 = ''; + const _image2 = ''; + const _image3 = ''; + const _image4 = ''; for (let y = 0; y < data.invoices.length; y++) { const invoice = data.invoices[y]; diff --git a/src/orders/application/__tests__/deb.service.spec.helper.ts b/src/orders/application/__tests__/deb.service.spec.helper.ts index 9c2c2d2..e8754a5 100644 --- a/src/orders/application/__tests__/deb.service.spec.helper.ts +++ b/src/orders/application/__tests__/deb.service.spec.helper.ts @@ -2,9 +2,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { DebService } from '../deb.service'; import { DebRepository } from '../../repositories/deb.repository'; -export const createMockRepository = ( - methods: Partial = {}, -) => +export const createMockRepository = (methods: Partial = {}) => ({ findByCpfCgcent: jest.fn(), ...methods, @@ -37,4 +35,3 @@ export async function createDebServiceTestModule( mockRepository, }; } - diff --git a/src/orders/application/__tests__/deb.service.spec.ts b/src/orders/application/__tests__/deb.service.spec.ts index 021f518..7377f3d 100644 --- a/src/orders/application/__tests__/deb.service.spec.ts +++ b/src/orders/application/__tests__/deb.service.spec.ts @@ -81,10 +81,7 @@ describe('DebService', () => { context.mockRepository.findByCpfCgcent.mockResolvedValue(mockDebs); - const result = await context.service.findByCpfCgcent( - '12345678900', - 1498, - ); + const result = await context.service.findByCpfCgcent('12345678900', 1498); expect(result).toHaveLength(1); expect(context.mockRepository.findByCpfCgcent).toHaveBeenCalledWith( @@ -178,9 +175,7 @@ describe('DebService', () => { it('deve propagar erro do repositório', async () => { const repositoryError = new Error('Database connection failed'); - context.mockRepository.findByCpfCgcent.mockRejectedValue( - repositoryError, - ); + context.mockRepository.findByCpfCgcent.mockRejectedValue(repositoryError); await expect( context.service.findByCpfCgcent('12345678900'), @@ -188,4 +183,3 @@ describe('DebService', () => { }); }); }); - diff --git a/src/orders/application/__tests__/orders.service.spec.helper.ts b/src/orders/application/__tests__/orders.service.spec.helper.ts index 3071b0b..a27d9d5 100644 --- a/src/orders/application/__tests__/orders.service.spec.helper.ts +++ b/src/orders/application/__tests__/orders.service.spec.helper.ts @@ -4,9 +4,7 @@ import { OrdersRepository } from '../../repositories/orders.repository'; import { IRedisClient } from '../../../core/configs/cache/IRedisClient'; import { RedisClientToken } from '../../../core/configs/cache/redis-client.adapter.provider'; -export const createMockRepository = ( - methods: Partial = {}, -) => +export const createMockRepository = (methods: Partial = {}) => ({ findOrders: jest.fn(), getCompletedDeliveries: jest.fn(), @@ -57,4 +55,3 @@ export async function createOrdersServiceTestModule( mockRedisClient, }; } - diff --git a/src/orders/application/__tests__/orders.service.spec.ts b/src/orders/application/__tests__/orders.service.spec.ts index c374881..a53fad0 100644 --- a/src/orders/application/__tests__/orders.service.spec.ts +++ b/src/orders/application/__tests__/orders.service.spec.ts @@ -87,7 +87,9 @@ describe('OrdersService', () => { const result = await context.service.findOrders(query); expect(result).toEqual(mockOrders); - expect(context.mockRepository.getCompletedDeliveries).not.toHaveBeenCalled(); + expect( + context.mockRepository.getCompletedDeliveries, + ).not.toHaveBeenCalled(); expect(result[0].completedDeliveries).toBeUndefined(); }); @@ -139,13 +141,19 @@ describe('OrdersService', () => { expect(result).toHaveLength(2); expect(result[0].completedDeliveries).toEqual(mockDeliveries1); expect(result[1].completedDeliveries).toEqual(mockDeliveries2); - expect(context.mockRepository.getCompletedDeliveries).toHaveBeenCalledTimes(2); - expect(context.mockRepository.getCompletedDeliveries).toHaveBeenCalledWith({ + expect( + context.mockRepository.getCompletedDeliveries, + ).toHaveBeenCalledTimes(2); + expect( + context.mockRepository.getCompletedDeliveries, + ).toHaveBeenCalledWith({ orderNumber: 12345, limit: 10, offset: 0, }); - expect(context.mockRepository.getCompletedDeliveries).toHaveBeenCalledWith({ + expect( + context.mockRepository.getCompletedDeliveries, + ).toHaveBeenCalledWith({ orderNumber: 12346, limit: 10, offset: 0, @@ -176,7 +184,9 @@ describe('OrdersService', () => { expect(result).toHaveLength(1); expect(result[0].completedDeliveries).toEqual([]); - expect(context.mockRepository.getCompletedDeliveries).toHaveBeenCalled(); + expect( + context.mockRepository.getCompletedDeliveries, + ).toHaveBeenCalled(); }); it('should handle empty orders array', async () => { @@ -273,7 +283,9 @@ describe('OrdersService', () => { const result = await context.service.findOrders(query); expect(result).toHaveLength(1); - expect(context.mockRepository.getCompletedDeliveries).toHaveBeenCalledWith({ + expect( + context.mockRepository.getCompletedDeliveries, + ).toHaveBeenCalledWith({ orderNumber: null, limit: 10, offset: 0, @@ -300,4 +312,3 @@ describe('OrdersService', () => { }); }); }); - diff --git a/src/orders/application/orders.service.ts b/src/orders/application/orders.service.ts index 181ae08..13efc82 100644 --- a/src/orders/application/orders.service.ts +++ b/src/orders/application/orders.service.ts @@ -66,7 +66,7 @@ export class OrdersService { deliveryQuery, ); order.completedDeliveries = deliveries; - } catch (error) { + } catch (_error) { order.completedDeliveries = []; } } @@ -242,7 +242,7 @@ export class OrdersService { deliveryQuery, ); orderDelivery.completedDeliveries = deliveries; - } catch (error) { + } catch (_error) { orderDelivery.completedDeliveries = []; } diff --git a/src/orders/dto/find-orders.dto.ts b/src/orders/dto/find-orders.dto.ts index 997cb1b..dda1344 100644 --- a/src/orders/dto/find-orders.dto.ts +++ b/src/orders/dto/find-orders.dto.ts @@ -13,7 +13,8 @@ export class FindOrdersDto { @IsOptional() @IsString() @ApiPropertyOptional({ - description: 'Código da filial (pode ser múltiplas filiais separadas por vírgula, ex: "1,2,3")', + description: + 'Código da filial (pode ser múltiplas filiais separadas por vírgula, ex: "1,2,3")', }) codfilial?: string; @@ -56,7 +57,8 @@ export class FindOrdersDto { @IsOptional() @IsString() @ApiPropertyOptional({ - description: 'Código do usuário 2 (pode ser múltiplos valores separados por vírgula)', + description: + 'Código do usuário 2 (pode ser múltiplos valores separados por vírgula)', }) codusur2?: string; diff --git a/src/orders/repositories/orders.repository.ts b/src/orders/repositories/orders.repository.ts index 5f388e8..db8cb00 100644 --- a/src/orders/repositories/orders.repository.ts +++ b/src/orders/repositories/orders.repository.ts @@ -419,9 +419,10 @@ WHERE .filter((c) => c) .map((c) => Number(c)) .filter((c) => !isNaN(c)); - const codusur2Condition = codusur2List.length === 1 - ? `AND PCPEDC.CODUSUR2 = :codusur2` - : `AND PCPEDC.CODUSUR2 IN (${codusur2List.join(',')})`; + const codusur2Condition = + codusur2List.length === 1 + ? `AND PCPEDC.CODUSUR2 = :codusur2` + : `AND PCPEDC.CODUSUR2 IN (${codusur2List.join(',')})`; conditions.push(codusur2Condition); } if (query.orderId) { diff --git a/src/products/__tests__/products.service.spec.helper.ts b/src/products/__tests__/products.service.spec.helper.ts index 9c5dd31..3c94dcc 100644 --- a/src/products/__tests__/products.service.spec.helper.ts +++ b/src/products/__tests__/products.service.spec.helper.ts @@ -38,4 +38,3 @@ export async function createProductsServiceTestModule( mockDataSource, }; } - diff --git a/src/products/__tests__/products.service.spec.ts b/src/products/__tests__/products.service.spec.ts index 9129de3..a9f9ee4 100644 --- a/src/products/__tests__/products.service.spec.ts +++ b/src/products/__tests__/products.service.spec.ts @@ -1,7 +1,6 @@ import { HttpException } from '@nestjs/common'; import { createProductsServiceTestModule } from './products.service.spec.helper'; import { ProductDetailQueryDto } from '../dto/product-detail-query.dto'; -import { ProductDetailResponseDto } from '../dto/product-detail-response.dto'; describe('ProductsService', () => { describe('getProductDetails', () => { @@ -147,12 +146,12 @@ describe('ProductsService', () => { codfilial: '1', }; - await expect( - context.service.getProductDetails(query), - ).rejects.toThrow(HttpException); - await expect( - context.service.getProductDetails(query), - ).rejects.toThrow('É necessário informar codprod ou codauxiliar.'); + await expect(context.service.getProductDetails(query)).rejects.toThrow( + HttpException, + ); + await expect(context.service.getProductDetails(query)).rejects.toThrow( + 'É necessário informar codprod ou codauxiliar.', + ); }); it('deve lançar exceção quando codauxiliar é array vazio', async () => { @@ -162,14 +161,13 @@ describe('ProductsService', () => { codfilial: '1', }; - await expect( - context.service.getProductDetails(query), - ).rejects.toThrow(HttpException); - await expect( - context.service.getProductDetails(query), - ).rejects.toThrow('É necessário informar codprod ou codauxiliar.'); + await expect(context.service.getProductDetails(query)).rejects.toThrow( + HttpException, + ); + await expect(context.service.getProductDetails(query)).rejects.toThrow( + 'É necessário informar codprod ou codauxiliar.', + ); }); }); }); }); - diff --git a/src/products/dto/product-detail-query.dto.ts b/src/products/dto/product-detail-query.dto.ts index 38e3542..a56aa36 100644 --- a/src/products/dto/product-detail-query.dto.ts +++ b/src/products/dto/product-detail-query.dto.ts @@ -1,5 +1,11 @@ import { ApiProperty } from '@nestjs/swagger'; -import { IsArray, IsNotEmpty, IsNumber, IsOptional, IsString } from 'class-validator'; +import { + IsArray, + IsNotEmpty, + IsNumber, + IsOptional, + IsString, +} from 'class-validator'; /** * DTO para requisição de detalhes de produtos @@ -14,7 +20,8 @@ export class ProductDetailQueryDto { numregiao: number; @ApiProperty({ - description: 'Array de códigos de produtos (opcional se codauxiliar for informado)', + description: + 'Array de códigos de produtos (opcional se codauxiliar for informado)', example: [1, 2, 3], type: [Number], required: false, @@ -24,7 +31,8 @@ export class ProductDetailQueryDto { codprod?: number[]; @ApiProperty({ - description: 'Array de códigos auxiliares (opcional se codprod for informado)', + description: + 'Array de códigos auxiliares (opcional se codprod for informado)', example: ['7891234567890', '7891234567891'], type: [String], required: false, diff --git a/src/products/dto/rotina-a4-query.dto.ts b/src/products/dto/rotina-a4-query.dto.ts index 4162426..737b0e4 100644 --- a/src/products/dto/rotina-a4-query.dto.ts +++ b/src/products/dto/rotina-a4-query.dto.ts @@ -22,7 +22,8 @@ export class RotinaA4QueryDto { codprod?: number; @ApiProperty({ - description: 'Código auxiliar do produto (opcional se codprod for informado)', + description: + 'Código auxiliar do produto (opcional se codprod for informado)', example: '7891234567890', required: false, }) @@ -37,4 +38,3 @@ export class RotinaA4QueryDto { @IsNotEmpty() codfilial: string; } - diff --git a/src/products/dto/rotina-a4-response.dto.ts b/src/products/dto/rotina-a4-response.dto.ts index c26bdfa..5854551 100644 --- a/src/products/dto/rotina-a4-response.dto.ts +++ b/src/products/dto/rotina-a4-response.dto.ts @@ -23,7 +23,8 @@ export class RotinaA4ResponseDto { CODAUXILIAR: string; @ApiProperty({ - description: 'Preço normal do produto formatado como moeda brasileira (com decimais)', + description: + 'Preço normal do produto formatado como moeda brasileira (com decimais)', example: '1.109,90', }) PRECO_NORMAL: string; @@ -35,7 +36,8 @@ export class RotinaA4ResponseDto { UNIDADE: string; @ApiProperty({ - description: 'Valor de venda formatado como moeda brasileira (sem decimais)', + description: + 'Valor de venda formatado como moeda brasileira (sem decimais)', example: 'R$ 2.499', }) VALOR_VENDA: string; @@ -52,4 +54,3 @@ export class RotinaA4ResponseDto { }) MARCA: string; } - diff --git a/src/products/dto/unified-product-search.dto.ts b/src/products/dto/unified-product-search.dto.ts index 53a84af..e1d0dde 100644 --- a/src/products/dto/unified-product-search.dto.ts +++ b/src/products/dto/unified-product-search.dto.ts @@ -29,4 +29,3 @@ export class UnifiedProductSearchDto { @IsNotEmpty() codfilial: string; } - diff --git a/src/products/products.controller.ts b/src/products/products.controller.ts index d3b536a..315013d 100644 --- a/src/products/products.controller.ts +++ b/src/products/products.controller.ts @@ -1,21 +1,33 @@ -/* eslint-disable prettier/prettier */ -/* eslint-disable @typescript-eslint/no-unused-vars */ - -import { Body, Controller, Get, Param, Post, Query, UseGuards } from '@nestjs/common'; +import { + Body, + Controller, + Get, + Param, + Post, + Query, + // UseGuards, // Comentado para uso futuro +} from '@nestjs/common'; import { ProductsService } from './products.service'; import { ExposedProduct } from 'src/core/models/exposed-product.model'; -import { JwtAuthGuard } from 'src/auth/guards/jwt-auth.guard'; +// import { JwtAuthGuard } from 'src/auth/guards/jwt-auth.guard'; // Comentado para uso futuro import { ExposedProductDto } from './dto/exposed-product.dto'; import { ProductValidationDto } from './dto/ProductValidationDto'; import { ProductEcommerceDto } from './dto/product-ecommerce.dto'; -import { ApiTags, ApiOperation, ApiParam, ApiQuery, ApiBody, ApiResponse, ApiBearerAuth } from '@nestjs/swagger'; +import { + ApiTags, + ApiOperation, + ApiParam, + ApiQuery, + ApiBody, + ApiResponse, + // ApiBearerAuth, // Comentado para uso futuro +} from '@nestjs/swagger'; import { ProductDetailQueryDto } from './dto/product-detail-query.dto'; import { ProductDetailResponseDto } from './dto/product-detail-response.dto'; import { RotinaA4QueryDto } from './dto/rotina-a4-query.dto'; import { RotinaA4ResponseDto } from './dto/rotina-a4-response.dto'; import { UnifiedProductSearchDto } from './dto/unified-product-search.dto'; - //@ApiBearerAuth() //@UseGuards(JwtAuthGuard) @ApiTags('Produtos') @@ -23,43 +35,57 @@ import { UnifiedProductSearchDto } from './dto/unified-product-search.dto'; export class ProductsController { constructor(private readonly productsService: ProductsService) {} - ///enpoit produtos-ecommecer + ///enpoit produtos-ecommecer @Get('products-ecommerce') @ApiOperation({ summary: 'Lista produtos para o e-commerce' }) - @ApiResponse({ - status: 200, + @ApiResponse({ + status: 200, description: 'Lista de produtos retornada com sucesso.', type: ProductEcommerceDto, - isArray: true + isArray: true, }) ///ENDPOIT DE VALIDAR PRODUTO POR FILTRO @Get('product-validation/:storeId/:filtro') - @ApiOperation({ summary: 'Valida produto pelo filtro (código, EAN ou descrição)' }) + @ApiOperation({ + summary: 'Valida produto pelo filtro (código, EAN ou descrição)', + }) @ApiParam({ name: 'storeId', type: String, description: 'ID da loja' }) - @ApiParam({ name: 'filtro', type: String, description: 'Filtro de busca (código, EAN ou descrição)' }) - @ApiQuery({ name: 'tipoBusca', required: false, enum: ['codauxiliar', 'codprod', 'descricao', 'todos'], description: 'Tipo de busca específica (opcional). Padrão: busca em todos os campos' }) - @ApiResponse({ - status: 200, - description: 'Produto encontrado com sucesso.', - type: ProductValidationDto + @ApiParam({ + name: 'filtro', + type: String, + description: 'Filtro de busca (código, EAN ou descrição)', + }) + @ApiQuery({ + name: 'tipoBusca', + required: false, + enum: ['codauxiliar', 'codprod', 'descricao', 'todos'], + description: + 'Tipo de busca específica (opcional). Padrão: busca em todos os campos', + }) + @ApiResponse({ + status: 200, + description: 'Produto encontrado com sucesso.', + type: ProductValidationDto, }) @ApiResponse({ status: 404, description: 'Produto não localizado.' }) async productValidation( @Param('storeId') storeId: string, @Param('filtro') filtro: string, - @Query('tipoBusca') tipoBusca?: 'codauxiliar' | 'codprod' | 'descricao' | 'todos', + @Query('tipoBusca') + tipoBusca?: 'codauxiliar' | 'codprod' | 'descricao' | 'todos', ): Promise { return this.productsService.productsValidation(storeId, filtro, tipoBusca); } - - - /// ENDPOIT PRODUTOS EXPOSTOS + /// ENDPOIT PRODUTOS EXPOSTOS @Post('exposed-product') @ApiOperation({ summary: 'Registra produto em exposição' }) @ApiBody({ type: ExposedProductDto }) - @ApiResponse({ status: 201, description: 'Produto exposto registrado com sucesso.' }) + @ApiResponse({ + status: 201, + description: 'Produto exposto registrado com sucesso.', + }) async exposedProduct(@Body() exposedProduct: ExposedProduct) { return this.productsService.exposedProduct(exposedProduct); } @@ -70,14 +96,16 @@ export class ProductsController { @Post('product-details') @ApiOperation({ summary: 'Busca detalhes de produtos com preço e estoque' }) @ApiBody({ type: ProductDetailQueryDto }) - @ApiResponse({ - status: 200, - description: 'Lista de produtos com detalhes retornada com sucesso.', + @ApiResponse({ + status: 200, + description: 'Lista de produtos com detalhes retornada com sucesso.', type: ProductDetailResponseDto, - isArray: true + isArray: true, }) @ApiResponse({ status: 400, description: 'Parâmetros inválidos.' }) - async getProductDetails(@Body() query: ProductDetailQueryDto): Promise { + async getProductDetails( + @Body() query: ProductDetailQueryDto, + ): Promise { return this.productsService.getProductDetails(query); } @@ -87,13 +115,18 @@ export class ProductsController { @Post('rotina-A4') @ApiOperation({ summary: 'Busca informações do produto conforme rotina A4' }) @ApiBody({ type: RotinaA4QueryDto }) - @ApiResponse({ - status: 200, - description: 'Dados do produto retornados com sucesso.', - type: RotinaA4ResponseDto + @ApiResponse({ + status: 200, + description: 'Dados do produto retornados com sucesso.', + type: RotinaA4ResponseDto, }) - @ApiResponse({ status: 404, description: 'Produto não encontrado para os parâmetros informados.' }) - async getRotinaA4(@Body() query: RotinaA4QueryDto): Promise { + @ApiResponse({ + status: 404, + description: 'Produto não encontrado para os parâmetros informados.', + }) + async getRotinaA4( + @Body() query: RotinaA4QueryDto, + ): Promise { return this.productsService.getRotinaA4(query); } @@ -101,16 +134,21 @@ export class ProductsController { * Endpoint para busca unificada de produtos por nome, código de barras ou codprod */ @Post('unified-search') - @ApiOperation({ summary: 'Busca unificada de produtos por nome, código de barras ou codprod' }) + @ApiOperation({ + summary: + 'Busca unificada de produtos por nome, código de barras ou codprod', + }) @ApiBody({ type: UnifiedProductSearchDto }) - @ApiResponse({ - status: 200, - description: 'Lista de produtos encontrados retornada com sucesso.', + @ApiResponse({ + status: 200, + description: 'Lista de produtos encontrados retornada com sucesso.', type: ProductDetailResponseDto, - isArray: true + isArray: true, }) @ApiResponse({ status: 400, description: 'Parâmetros inválidos.' }) - async unifiedProductSearch(@Body() query: UnifiedProductSearchDto): Promise { + async unifiedProductSearch( + @Body() query: UnifiedProductSearchDto, + ): Promise { return this.productsService.unifiedProductSearch(query); } } diff --git a/src/products/products.module.ts b/src/products/products.module.ts index f97a5e9..26601bd 100644 --- a/src/products/products.module.ts +++ b/src/products/products.module.ts @@ -1,19 +1,14 @@ -/* eslint-disable prettier/prettier */ - - -/* -https://docs.nestjs.com/modules -*/ - -import { Module } from '@nestjs/common'; -import { ProductsService } from './products.service'; -import { ProductsController } from './products.controller'; - -@Module({ - imports: [], - controllers: [ - ProductsController,], - providers: [ - ProductsService,], -}) -export class ProductsModule { } \ No newline at end of file +/* +https://docs.nestjs.com/modules +*/ + +import { Module } from '@nestjs/common'; +import { ProductsService } from './products.service'; +import { ProductsController } from './products.controller'; + +@Module({ + imports: [], + controllers: [ProductsController], + providers: [ProductsService], +}) +export class ProductsModule {} diff --git a/src/products/products.service.ts b/src/products/products.service.ts index 4dcdee0..14e320c 100644 --- a/src/products/products.service.ts +++ b/src/products/products.service.ts @@ -21,21 +21,23 @@ export class ProductsService { ): { whereCondition: string; useSingleParam: boolean } { if (tipoBusca === 'codauxiliar') { return { - whereCondition: 'PCPRODUT.CODAUXILIAR = REGEXP_REPLACE(:filtro, \'[^0-9]\', \'\')', + whereCondition: + "PCPRODUT.CODAUXILIAR = REGEXP_REPLACE(:filtro, '[^0-9]', '')", useSingleParam: true, }; } if (tipoBusca === 'codprod') { return { - whereCondition: 'PCPRODUT.CODPROD = REGEXP_REPLACE(:filtro, \'[^0-9]\', \'\')', + whereCondition: + "PCPRODUT.CODPROD = REGEXP_REPLACE(:filtro, '[^0-9]', '')", useSingleParam: true, }; } if (tipoBusca === 'descricao') { return { - whereCondition: 'PCPRODUT.DESCRICAO LIKE \'%\' || :filtro || \'%\'', + whereCondition: "PCPRODUT.DESCRICAO LIKE '%' || :filtro || '%'", useSingleParam: true, }; } @@ -170,7 +172,11 @@ export class ProductsService { const hasCodauxiliar = codauxiliar?.length > 0; if (hasCodprod && hasCodauxiliar) { - return this.buildWhereConditionWithBoth(codprod, codauxiliar, startParamIndex); + return this.buildWhereConditionWithBoth( + codprod, + codauxiliar, + startParamIndex, + ); } if (hasCodprod) { @@ -178,7 +184,10 @@ export class ProductsService { } if (hasCodauxiliar) { - return this.buildWhereConditionWithCodauxiliar(codauxiliar, startParamIndex); + return this.buildWhereConditionWithCodauxiliar( + codauxiliar, + startParamIndex, + ); } return { whereCondition: '', params: [], nextParamIndex: startParamIndex }; @@ -204,7 +213,11 @@ export class ProductsService { paramIndex++; }); - const whereCondition = `(PCPRODUT.CODPROD IN (${codprodPlaceholders.join(',')}) OR REGEXP_REPLACE(PCPRODUT.CODAUXILIAR, '[^0-9]', '') IN (${codauxiliarPlaceholders.join(',')}))`; + const whereCondition = `(PCPRODUT.CODPROD IN (${codprodPlaceholders.join( + ',', + )}) OR REGEXP_REPLACE(PCPRODUT.CODAUXILIAR, '[^0-9]', '') IN (${codauxiliarPlaceholders.join( + ',', + )}))`; params.push(...codprod); codauxiliar.forEach((aux) => { @@ -245,7 +258,9 @@ export class ProductsService { paramIndex++; }); - const whereCondition = `REGEXP_REPLACE(PCPRODUT.CODAUXILIAR, '[^0-9]', '') IN (${placeholders.join(',')})`; + const whereCondition = `REGEXP_REPLACE(PCPRODUT.CODAUXILIAR, '[^0-9]', '') IN (${placeholders.join( + ',', + )})`; codauxiliar.forEach((aux) => { params.push(aux.replace(/\D/g, '')); }); @@ -394,7 +409,7 @@ export class ProductsService { if (hasCodprod && hasCodauxiliar) { return { whereCondition: - 'and (pcprodut.codprod = :3 OR REGEXP_REPLACE(pcprodut.CODAUXILIAR, \'[^0-9]\', \'\') = REGEXP_REPLACE(:4, \'[^0-9]\', \'\'))', + "and (pcprodut.codprod = :3 OR REGEXP_REPLACE(pcprodut.CODAUXILIAR, '[^0-9]', '') = REGEXP_REPLACE(:4, '[^0-9]', ''))", params: [codprod, codauxiliar], }; } @@ -409,7 +424,7 @@ export class ProductsService { if (hasCodauxiliar) { return { whereCondition: - 'and REGEXP_REPLACE(pcprodut.CODAUXILIAR, \'[^0-9]\', \'\') = REGEXP_REPLACE(:3, \'[^0-9]\', \'\')', + "and REGEXP_REPLACE(pcprodut.CODAUXILIAR, '[^0-9]', '') = REGEXP_REPLACE(:3, '[^0-9]', '')", params: [codauxiliar], }; }