Criação do handler de autenticação, para um futuro microserviço de auth

This commit is contained in:
unknown
2025-03-31 08:31:14 -03:00
parent 2fd5ae2b1f
commit 69e10717e8
18 changed files with 433 additions and 748 deletions

2
.env
View File

@@ -12,5 +12,7 @@ POSTGRES_PASSWORD=ti
POSTGRES_DB=ksdb
JWT_SECRET=4557C0D7-DFB0-40DA-BF83-91A75103F7A9
JWT_EXPIRES_IN=8h

30
package-lock.json generated
View File

@@ -27,7 +27,7 @@
"aws-sdk": "^2.1692.0",
"axios": "^1.8.4",
"class-transformer": "^0.5.1",
"class-validator": "^0.6.8",
"class-validator": "^0.14.1",
"fs": "0.0.1-security",
"guid-typescript": "^1.0.9",
"https": "^1.0.0",
@@ -2750,6 +2750,12 @@
"@types/superagent": "*"
}
},
"node_modules/@types/validator": {
"version": "13.12.3",
"resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.12.3.tgz",
"integrity": "sha512-2ipwZ2NydGQJImne+FhNdhgRM37e9lCev99KnqkbFHd94Xn/mErARWI1RSLem1QA19ch5kOhzIZd7e8CA2FI8g==",
"license": "MIT"
},
"node_modules/@types/yargs": {
"version": "15.0.19",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.19.tgz",
@@ -4033,12 +4039,14 @@
}
},
"node_modules/class-validator": {
"version": "0.6.8",
"resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.6.8.tgz",
"integrity": "sha512-+G8KRwyk3J1pp1tHoIUkeH9/7GPfQLOZxfpiGXVQo0scGeB93IBlAm6SZ4Cur6mBEqL1lEOwdenPedIE/Rj9ew==",
"version": "0.14.1",
"resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.1.tgz",
"integrity": "sha512-2VEG9JICxIqTpoK1eMzZqaV+u/EiwEJkMGzTrZf6sU/fwsnOITVgYJ8yojSy6CaXtO9V0Cc6ZQZ8h8m4UBuLwQ==",
"license": "MIT",
"dependencies": {
"validator": ">=5.0.0"
"@types/validator": "^13.11.8",
"libphonenumber-js": "^1.10.53",
"validator": "^13.9.0"
}
},
"node_modules/cli-cursor": {
@@ -7856,6 +7864,12 @@
"node": ">=6"
}
},
"node_modules/libphonenumber-js": {
"version": "1.12.6",
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.6.tgz",
"integrity": "sha512-PJiS4ETaUfCOFLpmtKzAbqZQjCCKVu2OhTV4SVNNE7c2nu/dACvtCqj4L0i/KWNnIgRv7yrILvBj5Lonv5Ncxw==",
"license": "MIT"
},
"node_modules/lines-and-columns": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
@@ -11792,9 +11806,9 @@
}
},
"node_modules/validator": {
"version": "5.7.0",
"resolved": "https://registry.npmjs.org/validator/-/validator-5.7.0.tgz",
"integrity": "sha512-kHes0AATXms5NVgbJ4aDELR91O7+X+cxAS9d6I2z49MBhcAw6DYW4UCI8qv9NkL4+Mgx8jklt7gkCht+UHaZ+g==",
"version": "13.15.0",
"resolved": "https://registry.npmjs.org/validator/-/validator-13.15.0.tgz",
"integrity": "sha512-36B2ryl4+oL5QxZ3AzD0t5SsMNGvTtQHpjgFO5tbNxfXbMFkY822ktCDe1MnlqV3301QQI9SLHDNJokDI+Z9pA==",
"license": "MIT",
"engines": {
"node": ">= 0.10"

View File

@@ -38,7 +38,7 @@
"aws-sdk": "^2.1692.0",
"axios": "^1.8.4",
"class-transformer": "^0.5.1",
"class-validator": "^0.6.8",
"class-validator": "^0.14.1",
"fs": "0.0.1-security",
"guid-typescript": "^1.0.9",
"https": "^1.0.0",

View File

@@ -8,7 +8,7 @@
import { ProductsModule } from './products/products.module';
import { AuthModule } from './auth/auth/auth.module';
import { DataConsultModule } from './data-consult/data-consult.module';
import { OrdersModule } from './orders/modules/orders.module';
import { OrdersModule } from './orders/orders.module';
import { OcorrencesController } from './crm/occurrences/ocorrences.controller';
import { OccurrencesModule } from './crm/occurrences/occurrences.module';
import { ReasonTableModule } from './crm/reason-table/reason-table.module';
@@ -17,13 +17,16 @@
import { LogisticController } from './logistic/logistic.controller';
import { LogisticService } from './logistic/logistic.service';
import { LoggerModule } from './Log/logger.module';
import jwtConfig from './auth/jwt.config';
import { UsersModule } from './auth/users/users.module';
@Module({
imports: [
UsersModule,
ConfigModule.forRoot({ isGlobal: true }),
ConfigModule.forRoot({ isGlobal: true,
load: [jwtConfig]
}),
TypeOrmModule.forRootAsync({
name: 'oracle',
inject: [ConfigService],

View File

@@ -1,7 +1,7 @@
export class AuthenticateUserCommand {
constructor(
public readonly username: string,
public readonly password: string,
) {}
}
export class AuthenticateUserCommand {
constructor(
public readonly username: string,
public readonly password: string,
) {}
}

View File

@@ -17,7 +17,7 @@ export class AuthenticateUserService {
}
if (user.dataDesligamento !== null) {
return Result.fail('Usuário desligado da empresa, login não permitido!');
return Result.fail('Usuário desligado da empresa, login não permitido, Procure o setor de RH!');
}
if (user.situacao === 'I') {

4
src/auth/jwt.config.ts Normal file
View File

@@ -0,0 +1,4 @@
export default () => ({
jwtSecret: process.env.JWT_SECRET || 'fallback-secret',
jwtExpiresIn: process.env.JWT_EXPIRES_IN || '8h',
});

View File

@@ -1,7 +1,8 @@
// ✅ jwt.strategy.ts
import { Inject, Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { ConfigService } from '@nestjs/config';
import { JwtPayload } from '../models/jwt-payload.model';
import { UserRepository } from '../../auth/users/UserRepository';
import { RedisClientToken } from '../../core/configs/cache/redis-client.adapter.provider';
@@ -12,32 +13,38 @@ export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(
@Inject(RedisClientToken) private readonly redis: IRedisClient,
private readonly userRepository: UserRepository,
private readonly configService: ConfigService,
) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: '4557C0D7-DFB0-40DA-BF83-91A75103F7A9',
secretOrKey: configService.get<string>('jwtSecret'),
});
}
async validate(payload: JwtPayload) {
const sessionKey = `session:${payload.id}`;
const user = await this.redis.get<any>(sessionKey);
const sessionKey = this.buildSessionKey(payload.id);
const cachedUser = await this.redis.get<any>(sessionKey);
if (user) {
// Audit log placeholder
// await this.auditAccess(user);
return user;
if (cachedUser) {
// await this.auditAccess(cachedUser);
return cachedUser;
}
const userDb = await this.userRepository.findById(payload.id);
if (!userDb || userDb.situacao === 'I' || userDb.dataDesligamento) {
const user = await this.userRepository.findById(payload.id);
if (!user || user.situacao === 'I' || user.dataDesligamento) {
throw new UnauthorizedException('Usuário inválido ou inativo');
}
await this.redis.set(sessionKey, userDb, 60 * 60 * 8);
// Audit fallback
// await this.auditAccess(userDb, 'fallback');
await this.redis.set(sessionKey, user, 60 * 60 * 8); // 8h
return userDb;
return {
id: user.id,
name: user.name,
email: user.email,
};
}
private buildSessionKey(userId: number): string {
return `auth:sessions:${userId}`;
}
}

View File

@@ -1,4 +1,3 @@
// common/interceptors/response.interceptor.ts
import {
CallHandler,
ExecutionContext,

View File

@@ -15,7 +15,7 @@ import {
Post,
UseGuards
} from '@nestjs/common';
import { JwtAuthGuard } from 'src/auth/guards/jwt-auth.guard'; // ajuste o caminho se necessário
import { JwtAuthGuard } from 'src/auth/guards/jwt-auth.guard';
import { ApiBearerAuth, ApiTags, ApiOperation } from '@nestjs/swagger';

View File

@@ -166,7 +166,7 @@ export class LogisticService {
}
async getEmployee() {
const dataSource = new DataSource(createPostgresConfig(this.configService));
const dataSource = new DataSource(createOracleConfig(this.configService));
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();

View File

@@ -10,6 +10,7 @@ async function bootstrap() {
app.useGlobalInterceptors(new ResponseInterceptor());
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
@@ -36,6 +37,6 @@ async function bootstrap() {
SwaggerModule.setup('docs', app, document);
await app.listen(9001);
await app.listen(8066);
}
bootstrap();

View File

@@ -0,0 +1,14 @@
import { Injectable } from '@nestjs/common';
import { FindOrdersDto } from '../dto/find-orders.dto';
import { OrdersRepository } from '../repositories/orders.repository';
@Injectable()
export class OrdersService {
constructor(private readonly ordersRepository: OrdersRepository) {}
async findOrders(query: FindOrdersDto) {
return await this.ordersRepository.findOrders(query);
}
}

View File

@@ -0,0 +1,99 @@
import { ApiPropertyOptional } from '@nestjs/swagger';
import {
IsOptional,
IsString,
IsNumber,
IsDateString,
IsIn,
} from 'class-validator';
export class FindOrdersDto {
@IsOptional()
@IsString()
@ApiPropertyOptional()
storeId?: string;
@IsOptional()
@IsString()
@ApiPropertyOptional()
storeStockId?: string;
@IsOptional()
@IsNumber()
@ApiPropertyOptional()
sellerId?: number;
@IsOptional()
@IsNumber()
@ApiPropertyOptional()
customerId?: number;
@IsOptional()
@IsString()
@ApiPropertyOptional()
billingId?: string;
@IsOptional()
@IsNumber()
@ApiPropertyOptional()
orderId?: number;
@IsOptional()
@IsNumber()
@ApiPropertyOptional()
invoiceId?: number;
@IsOptional()
@IsNumber()
@ApiPropertyOptional()
productId?: number;
@IsOptional()
@IsDateString()
@ApiPropertyOptional()
createDateIni?: string;
@IsOptional()
@IsDateString()
@ApiPropertyOptional()
createDateEnd?: string;
@IsOptional()
@IsDateString()
@ApiPropertyOptional()
invoiceDateIni?: string;
@IsOptional()
@IsDateString()
@ApiPropertyOptional()
invoiceDateEnd?: string;
@IsOptional()
@IsNumber()
@ApiPropertyOptional()
shippimentId?: number;
@IsOptional()
@IsString()
@ApiPropertyOptional()
deliveryType?: string;
@IsOptional()
@IsString()
@ApiPropertyOptional()
status?: string;
@IsOptional()
@IsString()
@ApiPropertyOptional()
type?: string;
@IsOptional()
@IsIn(['S', 'N'])
@ApiPropertyOptional()
onlyPendentingTransfer?: string;
}

View File

@@ -1,55 +1,33 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
// src/modules/orders/interfaces/controllers/orders.controller.ts
/*
https://docs.nestjs.com/controllers#controllers
*/
import { Body, Controller, Get, Param, Post, Query } from '@nestjs/common';
import { OrdersService } from './orders.service';
import {
Body,
Controller,
Get,
Param,
Post,
Query,
UsePipes,
UseGuards,
ValidationPipe,
} from '@nestjs/common';
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
import { ResponseInterceptor } from '../common/response.interceptor';
import { OrdersService } from './application/orders.service';
import { FindOrdersDto } from './dto/find-orders.dto';
import { JwtAuthGuard } from 'src/auth/guards/jwt-auth.guard';
@ApiTags('Orders')
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@Controller('api/v1/orders')
export class OrdersController {
constructor(private readonly ordersService: OrdersService) {}
constructor( private readonly ordersService: OrdersService) {}
@Get('find')
@UsePipes(new ValidationPipe({ transform: true }))
findOrders(@Query() query: FindOrdersDto) {
return this.ordersService.findOrders(query);
}
@Get('find')
findOrders(@Query() query) {
return this.ordersService.findOrders(query);
}
@Get('invoice/:chavenfe')
findInvoice(@Param('chavenfe') chavenfe: string) {
return this.ordersService.findInvoice(chavenfe);
}
@Get('itens/:id')
getItens(@Param('id') id: string) {
return this.ordersService.getItens(id);
}
@Get('cut-itens/:id')
getCutItens(@Param('id') id: string) {
return this.ordersService.getCutItens(id);
}
@Get('delivery/:id')
getOrderDelivery(@Param('id') id: string) {
return this.ordersService.getOrderDelivery(id);
}
@Get('transfer/:id')
getTransfer(@Param('id') id: number) {
return this.ordersService.getTransfer(id);
}
@Get('status/:id')
getStatusOrder(@Param('id') id: number) {
return this.ordersService.getStatusOrder(id);
}
@Post('invoice-check')
createInvoiceCheck(@Body() invoice: any) {
return this.ordersService.createInvoiceCheck(invoice);
}
}
}

View File

@@ -1,19 +1,16 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
import { OrdersService } from './orders.service';
import { OrdersController } from './orders.controller';
/*
https://docs.nestjs.com/modules
*/
// src/modules/orders/orders.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { OrdersService } from './application/orders.service';
import { OrdersController } from './orders.controller';
import { OrdersRepository } from './repositories/orders.repository';
@Module({
imports: [],
controllers: [
OrdersController,],
providers: [
OrdersService,],
imports: [
TypeOrmModule,
],
controllers: [OrdersController],
providers: [OrdersService, OrdersRepository],
})
export class OrdersModule { }
export class OrdersModule {}

View File

@@ -1,648 +0,0 @@
/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
https://docs.nestjs.com/providers#services
*/
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { createOracleConfig } from '../core/configs/typeorm.oracle.config';
import { DataSource } from 'typeorm';
@Injectable()
export class OrdersService {
async findOrders(query) {
const dataSource = new DataSource(createOracleConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
let sql = `SELECT PCPEDC.DATA as "createDate"
,PCPEDC.CODFILIAL || CASE WHEN PCPEDC.CODFILIALLOJA IS NOT NULL THEN
' - Pre-Box ('||PCPEDC.CODFILIALLOJA||')'
ELSE NULL END as "storeId"
,PCPEDC.NUMPED as "orderId"
,PCPEDC.CODCLI as "customerId"
,PCPEDC.CODCLI||' - '||PCCLIENT.CLIENTE as "customerName"
,PCPEDC.CODUSUR as "sellerId"
,PCPEDC.CODUSUR||' - '||PCUSUARI.NOME as "sellerName"
,PCSUPERV.NOME as "store"
,( SELECT CASE WHEN PCPEDI.TIPOENTREGA = 'EN' THEN 'Entrega ('||PCPEDI.TIPOENTREGA||')'
WHEN PCPEDI.TIPOENTREGA = 'EF' THEN 'Entrega Futura ('||PCPEDI.TIPOENTREGA||')'
WHEN PCPEDI.TIPOENTREGA = 'RP' THEN 'Retira Posterior ('||PCPEDI.TIPOENTREGA||')'
WHEN PCPEDI.TIPOENTREGA = 'RI' THEN 'Retira Imediata ('||PCPEDI.TIPOENTREGA||')'
ELSE 'Não Informado' END
FROM PCPEDI
WHERE PCPEDI.NUMPED = PCPEDC.NUMPED
AND ROWNUM = 1 ) as "deliveryType"
,CASE WHEN NVL(PCPEDC.CODENDENTCLI,0) = 0 THEN
( SELECT PCPRACA.CODPRACA||'-'||PCPRACA.PRACA
FROM PCPRACA
WHERE PCPRACA.CODPRACA = PCPEDC.CODPRACA )
ELSE ( SELECT PCPRACA.CODPRACA||'-'||PCPRACA.PRACA
FROM PCCLIENTENDENT, PCPRACA
WHERE PCCLIENTENDENT.CODCLI = PCPEDC.CODCLI
AND PCCLIENTENDENT.CODENDENTCLI = PCPEDC.CODENDENTCLI
AND PCCLIENTENDENT.CODPRACAENT = PCPRACA.CODPRACA ) END as "deliveryLocal"
,CASE WHEN NVL(PCPEDC.CODENDENTCLI,0) = 0 THEN
( SELECT PCROTAEXP.CODROTA||'-'||PCROTAEXP.DESCRICAO
FROM PCPRACA, PCROTAEXP
WHERE PCPRACA.CODPRACA = PCPEDC.CODPRACA
AND PCPRACA.ROTA = PCROTAEXP.CODROTA )
ELSE ( SELECT PCROTAEXP.CODROTA||'-'||PCROTAEXP.DESCRICAO
FROM PCCLIENTENDENT, PCPRACA, PCROTAEXP
WHERE PCCLIENTENDENT.CODCLI = PCPEDC.CODCLI
AND PCCLIENTENDENT.CODENDENTCLI = PCPEDC.CODENDENTCLI
AND PCCLIENTENDENT.CODPRACAENT = PCPRACA.CODPRACA
AND PCPRACA.ROTA = PCROTAEXP.CODROTA ) END as "masterDeliveryLocal"
,CASE WHEN PCPEDC.CONDVENDA = 1 THEN 'TV1 - Retira Imediata'
WHEN PCPEDC.CONDVENDA = 7 THEN 'TV7 - Faturamento'
WHEN PCPEDC.CONDVENDA = 8 THEN 'TV8 - Entrega (' ||
( SELECT PCPEDI.TIPOENTREGA FROM PCPEDI
WHERE PCPEDI.NUMPED = PCPEDC.NUMPED
AND ROWNUM = 1 ) ||')'
WHEN PCPEDC.CONDVENDA = 10 THEN 'TV10 - Transferência'
ELSE 'Outros' END as "orderType"
,CASE WHEN PCPEDC.POSICAO = 'P' THEN 'Pendente'
WHEN PCPEDC.POSICAO = 'B' THEN 'Bloqueado'
WHEN PCPEDC.POSICAO = 'L' THEN 'Liberado'
WHEN PCPEDC.POSICAO = 'M' THEN 'Montado'
WHEN PCPEDC.POSICAO = 'F' THEN 'Faturado'
WHEN PCPEDC.POSICAO = 'C' THEN 'Cancelado'
END as "status"
,CASE WHEN PCPEDC.CONDVENDA IN (1,7) THEN PCPEDC.VLATEND ELSE PCPEDC.VLTOTAL END as "amount"
,PCPEDC.DTENTREGA as "deliveryDate"
,CASE WHEN PCPEDC.tipoprioridadeentrega = 'B' THEN 'Baixa'
WHEN PCPEDC.TIPOPRIORIDADEENTREGA = 'M' THEN 'Média'
WHEN PCPEDC.TIPOPRIORIDADEENTREGA = 'A' THEN 'Alta'
ELSE 'Não Definido' END as "deliveryPriority"
,PCPEDC.NUMCAR as "shipmentId"
,PCPEDC.DTLIBERA as "releaseDate"
,PCPEDC.CODFUNCLIBERA as "releaseUser"
,PCPEDC.CODFUNCLIBERA||'-'||
(SELECT PCEMPR.NOME FROM PCEMPR WHERE PCEMPR.MATRICULA = PCPEDC.CODFUNCLIBERA) as "releaseUserName"
,PCCARREG.DTSAIDA as "shipmentDate"
,PCCARREG.DATAMON as "shipmentDateCreate"
,CASE WHEN PCPEDC.NUMCAR = 0 THEN NULL
ELSE PCCARREG.DTFECHA END as "shipmentCloseDate"
,PCPEDC.CODPLPAG as "paymentId"
,PCPLPAG.DESCRICAO as "paymentName"
,PCPEDC.CODCOB as "billingId"
,PCPEDC.CODCOB||'-'||
PCCOB.COBRANCA as "billingName"
,PCPEDC.DTFAT as "invoiceDate"
,PCPEDC.HORAFAT as "invoiceHour"
,PCPEDC.MINUTOFAT as "invoiceMinute"
,PCPEDC.NUMNOTA as "invoiceNumber"
,PCPEDC.MOTIVOPOSICAO as "BloqDescription"
,PCNFSAID.DTCANHOTO as "confirmDeliveryDate"
,PCPEDC.TOTPESO as "totalWeigth"
,CASE WHEN PCNFSAID.DTCANHOTO IS NOT NULL THEN 4
WHEN PCPEDC.POSICAO = 'F' THEN 3
WHEN PCPEDC.DTFINALSEP IS NOT NULL THEN 2
WHEN PCPEDC.POSICAO = 'M' THEN 1
WHEN PCPEDC.POSICAO IN ('L', 'P', 'B') THEN 0
ELSE 0 END as "processOrder"
,( SELECT COUNT(1) FROM PCPREST, PCNFSAID, PCPEDC PED_VGER
WHERE PCPREST.NUMTRANSVENDA = PCNFSAID.NUMTRANSVENDA
AND PCNFSAID.NUMTRANSVENDA = PED_VGER.NUMTRANSVENDA
AND PED_VGER.NUMPED = PCPEDC.NUMPEDENTFUT
AND PCPREST.DTPAG IS NULL
AND PCPREST.CODCOB = 'VGER' ) as "payment"
,MOTORISTA.MATRICULA || ' - ' || MOTORISTA.NOME as "driver"
,PCPEDC.NUMPEDENTFUT as "orderSaleId"
,PCVEICUL.DESCRICAO||' ( '|| PCVEICUL.PLACA||' )' as "carDescription"
,PCVEICUL.PLACA as "carIdentification"
,PCPEDC.CODFORNECFRETE||' - '||PCFORNEC.FORNECEDOR as "carrier"
,CASE WHEN (SELECT COUNT(1) FROM PCNFENT, PCFILIAL
WHERE PCFILIAL.CODIGO = PCPEDC.CODFILIAL
AND PCFILIAL.CODFORNEC = PCNFENT.CODFORNEC
AND PCNFENT.NUMNOTA = PCPEDC.NUMNOTA ) = 0
AND PCPEDC.CONDVENDA = 10
AND PCPEDC.POSICAO = 'F' THEN 'Em Trânsito'
WHEN PCPEDC.POSICAO = 'M'
AND PCPEDC.CONDVENDA = 10 THEN 'Em Separação'
WHEN PCPEDC.POSICAO IN ( 'L', 'P' )
AND PCPEDC.CONDVENDA = 10 THEN 'Aguardando Separação'
WHEN PCPEDC.CONDVENDA NOT IN ( 10 ) THEN NULL
ELSE 'Concluída' END as "statusTransfer"
,PCPEDC.CODFILIALLOJA as "storePreBox"
FROM PCPEDC, PCCLIENT, PCUSUARI, PCSUPERV, PCCOB, PCPLPAG, PCCARREG, PCNFSAID,
PCEMPR MOTORISTA, PCVEICUL, PCFORNEC
WHERE PCPEDC.CODCLI = PCCLIENT.CODCLI
AND PCPEDC.CODUSUR = PCUSUARI.CODUSUR
AND PCPEDC.CODPLPAG = PCPLPAG.CODPLPAG
AND PCPEDC.CODCOB = PCCOB.CODCOB
AND PCPEDC.CODSUPERVISOR = PCSUPERV.CODSUPERVISOR
AND PCPEDC.NUMTRANSVENDA = PCNFSAID.NUMTRANSVENDA (+)
AND PCPEDC.NUMCAR = PCCARREG.NUMCAR (+)
AND PCCARREG.CODMOTORISTA = MOTORISTA.MATRICULA (+)
AND PCCARREG.CODVEICULO = PCVEICUL.CODVEICULO (+)
AND PCPEDC.CODFORNECFRETE = PCFORNEC.CODFORNEC (+)`;
let sqlWhere = "";
if (query.storeId) {
sqlWhere += ` AND PCPEDC.CODFILIAL = '${query.storeId}'`;
}
if (query.storeStockId) {
sqlWhere += ` AND EXISTS(SELECT PCPEDI.CODPROD FROM PCPEDI
WHERE PCPEDI.NUMPED = PCPEDC.NUMPED
AND PCPEDI.CODFILIALRETIRA = '${query.storeStockId}' )`;
}
if (query.sellerId) {
sqlWhere += ` AND PCPEDC.CODUSUR = ${query.sellerId}`;
}
if (query.customerId) {
sqlWhere += ` AND PCPEDC.CODCLI = ${query.customerId}`;
}
if (query.billingId) {
sqlWhere += ` AND PCPEDC.CODCOB = '${query.billingId}'`;
}
if (query.orderId) {
sqlWhere += ` AND ( PCPEDC.NUMPED = ${query.orderId} or PCPEDC.NUMPEDENTFUT = ${query.orderId} )`;
}
if (query.invoiceId) {
sqlWhere += ` AND PCPEDC.NUMNOTA = ${query.invoiceId}`;
}
if (query.productId) {
sqlWhere += ` AND EXISTS(SELECT PCPEDI.CODPROD FROM PCPEDI
WHERE PCPEDI.NUMPED = PCPEDC.NUMPED
AND PCPEDI.CODPROD = ${query.productId} )`;
}
if (query.createDateIni) {
sqlWhere += ` AND PCPEDC.DATA >= TO_DATE('${query.createDateIni}', 'YYYY-MM-DD')`;
}
if (query.createDateEnd) {
sqlWhere += ` AND PCPEDC.DATA <= TO_DATE('${query.createDateEnd}', 'YYYY-MM-DD')`;
}
if (query.invoiceDateIni) {
sqlWhere += ` AND PCPEDC.DTFAT >= TO_DATE('${query.invoiceDateIni}', 'YYYY-MM-DD')`;
}
if (query.invoiceDateEnd) {
sqlWhere += ` AND PCPEDC.DTFAT <= TO_DATE('${query.invoiceDateEnd}', 'YYYY-MM-DD')`;
}
if (query.shippimentId) {
sqlWhere += ` AND PCPEDC.NUMCAR = ${query.shippimentId}`;
}
if (query.deliveryType) {
const deliveryType: string[] = query.deliveryType.split(',');
const listDeliveryType = deliveryType.map(type => `'${type}'`)
sqlWhere += ` AND EXISTS(SELECT PCPEDI.CODPROD FROM PCPEDI
WHERE PCPEDI.NUMPED = PCPEDC.NUMPED
AND PCPEDI.TIPOENTREGA IN ( ${listDeliveryType} ) )`;
}
if (query.status) {
const statusOrder: string[] = query.status.split(',');
const listStatusOrder = statusOrder.map(status => `'${status}'`)
sqlWhere += ` AND PCPEDC.POSICAO IN ( ${listStatusOrder} )`;
}
if (query.type) {
const typeOrder: string[] = query.type.split(',');
const listTypeOrder = typeOrder.map(type => `'${type}'`)
sqlWhere += ` AND PCPEDC.CONDVENDA IN ( ${listTypeOrder} )`;
}
if (query.onlyPendentingTransfer && query.onlyPendentingTransfer == "S") {
sqlWhere += ` AND NOT EXISTS(SELECT PCNFENT.NUMTRANSENT FROM PCNFENT, PCFILIAL
WHERE PCFILIAL.CODIGO = PCPEDC.CODFILIAL
AND PCFILIAL.CODFORNEC = PCNFENT.CODFORNEC
AND PCNFENT.NUMNOTA = PCPEDC.NUMNOTA ) `
}
sql += sqlWhere;
sql += ' AND ROWNUM < 5000';
const orders = await queryRunner.manager.query(sql);
return orders;
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async findInvoice(chavenfe: string) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `select pcnfsaid.codfilial as "storeId",
pcnfsaid.dtsaida as "invoiceDate",
pcnfsaid.numped as "orderId",
pcnfsaid.numnota as "invoiceId",
pcnfsaid.numtransvenda as "transactionId",
pcnfsaid.codcli as "customerId",
pcclient.cliente as "customer",
pcnfsaid.codusur as "sellerId",
pcusuari.nome as "sellerName",
( select sum(pcmov.qt) from pcmov where pcmov.numtransvenda = pcnfsaid.numtransvenda ) as "itensQt",
null as "itens"
from pcnfsaid, pcclient, pcusuari
where pcnfsaid.codcli = pcclient.codcli
and pcnfsaid.codusur = pcusuari.codusur
and pcnfsaid.chavenfe = '${chavenfe}'`;
const invoice = await queryRunner.manager.query(sql);
if ( invoice == null || invoice.length == 0 ) {
throw new HttpException('Nota fiscal não foi localizada na sistema', HttpStatus.BAD_REQUEST);
}
const sqlItem = `select pcmov.codprod as "productId"
,pcprodut.descricao as "productName"
,pcprodut.embalagem as "package"
,pcmov.qt as "qt"
,pcprodut.codauxiliar as "ean"
,pcprodut.multiplo as "multiple"
,pcprodut.tipoproduto as "productType"
,REPLACE(CASE WHEN INSTR(PCPRODUT.URLIMAGEM, ';') > 0 THEN
SUBSTR(PCPRODUT.URLIMAGEM,1,INSTR(PCPRODUT.URLIMAGEM, ';') - 1)
WHEN PCPRODUT.URLIMAGEM IS NOT NULL THEN
PCPRODUT.URLIMAGEM
ELSE NULL END, '167.249.211.178:8001', '10.1.1.191') as "image"
from pcmov, pcprodut
where pcmov.codprod = pcprodut.codprod
and pcmov.numtransvenda = ${invoice[0].transactionId}`;
const itens = await queryRunner.manager.query(sqlItem);
const sqlProduct = `SELECT PCPRODUT.URLIMAGEM FROM PCPRODUT WHERE CODPROD = `
invoice[0].itens = [...itens];
return invoice[0];
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async getItens(orderId: string) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `SELECT PCPEDI.CODPROD as "productId"
, PCPRODUT.DESCRICAO as "description"
, PCPRODUT.EMBALAGEM as "pacth"
, NVL(PCPEDI.COMPLEMENTO,
( SELECT TV7I.COMPLEMENTO FROM PCPEDC, PCPEDC TV7, PCPEDITEMP TV7I
WHERE TV7.NUMPED = PCPEDC.NUMPEDENTFUT
AND PCPEDC.NUMPED = PCPEDI.NUMPED
AND TV7.NUMPEDRCA = TV7I.NUMPEDRCA
AND TV7I.CODPROD = PCPEDI.codprod
AND TV7I.NUMSEQ = PCPEDI.NUMSEQ ) ) as "color"
, PCPEDI.CODFILIALRETIRA as "stockId"
, PCPEDI.QT as "quantity"
, PCPEDI.PVENDA as "salePrice"
, CASE WHEN PCPEDI.TIPOENTREGA = 'RI' THEN 'RETIRA IMEDIATA'
WHEN PCPEDI.TIPOENTREGA = 'RP' THEN 'RETIRA POSTERIOR'
WHEN PCPEDI.TIPOENTREGA = 'EN' THEN 'ENTREGA'
WHEN PCPEDI.TIPOENTREGA = 'EF' THEN 'ENTREGA FUTURA'
END as "deliveryType"
, ( PCPEDI.QT *
PCPEDI.PVENDA ) as "total"
, ( PCPEDI.QT * PCPRODUT.PESOBRUTO ) as "weigth"
, PCDEPTO.DESCRICAO as "department"
, PCMARCA.MARCA as "brand"
FROM PCPEDI, PCPRODUT, PCDEPTO, PCMARCA
WHERE PCPEDI.CODPROD = PCPRODUT.CODPROD
AND PCPRODUT.CODEPTO = PCDEPTO.CODEPTO
AND PCPRODUT.CODMARCA = PCMARCA.CODMARCA
AND PCPEDI.NUMPED = ${orderId}`;
const itens = await queryRunner.manager.query(sql);
return itens;
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async getCutItens(orderId: string) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `SELECT PCCORTEI.CODPROD as "productId"
, PCPRODUT.DESCRICAO as "description"
, PCPRODUT.EMBALAGEM as "pacth"
, PCCORTEI.CODFILIAL as "stockId"
, ( PCCORTEI.QTSEPARADA +
PCCORTEI.QTCORTADA ) as "saleQuantity"
, PCCORTEI.QTCORTADA as "cutQuantity"
, PCCORTEI.QTSEPARADA as "separedQuantity"
FROM PCCORTEI, PCPRODUT
WHERE PCCORTEI.CODPROD = PCPRODUT.CODPROD
AND PCCORTEI.NUMPED = ${orderId}`;
const itens = await queryRunner.manager.query(sql);
return itens;
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async getOrderDelivery(orderId: string){
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `SELECT PCPRACA.CODPRACA as "placeId"
,PCPRACA.PRACA as "placeName"
,NVL(ENDENT.ENDERENT, PCCLIENT.ENDERENT) as "street"
,NVL(ENDENT.NUMEROENT, PCCLIENT.NUMEROENT) as "addressNumber"
,NVL(ENDENT.BAIRROENT, PCCLIENT.BAIRROENT) as "bairro"
,NVL(ENDENT.MUNICENT, PCCLIENT.MUNICENT) as "city"
,NVL(ENDENT.ESTENT, PCCLIENT.ESTENT) as "state"
,NVL(ENDENT.COMPLEMENTOENT, PCCLIENT.COMPLEMENTOENT) as "addressComplement"
,NVL(ENDENT.CEPENT, PCCLIENT.CEPENT) as "cep"
,PCPEDC.OBS1 as "commentOrder1"
,PCPEDC.OBS2 as "commentOrder2"
,PCPEDC.OBSENTREGA1 as "commentDelivery1"
,PCPEDC.OBSENTREGA2 as "commentDelivery2"
,PCPEDC.OBSENTREGA3 as "commentDelivery3"
,PCPEDC.OBSENTREGA4 as "commentDelivery4"
,PCPEDC.NUMCAR as "shippimentId"
,PCCARREG.DTSAIDA as "shippimentDate"
,PCCARREG.DESTINO as "shippimentComment"
,PCROTAEXP.DESCRICAO as "place"
,PCEMPR.MATRICULA||'-'||
PCEMPR.NOME as "driver"
,PCVEICUL.PLACA||' - '||PCVEICUL.DESCRICAO as "car"
,CASE WHEN PCCARREG.DTFECHA < PCCARREG.DTSAIDA THEN NULL
ELSE PCCARREG.DTFECHA END as "closeDate"
,SEPARADOR.NOME as "separatorName"
,CONFERENTE.NOME as "confName"
,PCPEDC.DTLIBERA as "releaseDate"
FROM PCPEDC, PCCLIENT, PCPRACA, PCCLIENTENDENT ENDENT, PCCARREG, PCVEICUL, PCEMPR, PCROTAEXP,
PCEMPR SEPARADOR, PCEMPR CONFERENTE
WHERE NVL(ENDENT.CODPRACAENT, PCPEDC.CODPRACA) = PCPRACA.CODPRACA
AND PCPEDC.CODCLI = PCCLIENT.CODCLI
AND PCPEDC.CODENDENTCLI = ENDENT.CODENDENTCLI (+)
AND PCPEDC.CODCLI = ENDENT.CODCLI (+)
AND PCPEDC.NUMCAR = PCCARREG.NUMCAR (+)
AND PCCARREG.CODMOTORISTA = PCEMPR.MATRICULA (+)
AND PCCARREG.CODVEICULO = PCVEICUL.CODVEICULO (+)
AND PCCARREG.CODROTAPRINC = PCROTAEXP.CODROTA (+)
AND PCPEDC.CODFUNCSEP = SEPARADOR.MATRICULA (+)
AND PCPEDC.CODFUNCCONF = CONFERENTE.MATRICULA (+)
AND PCPEDC.NUMPED = ${orderId}`;
const orderDelivery = await queryRunner.manager.query(sql);
if ( orderDelivery.length > 0 ) {
return orderDelivery[0];
} else {
return null;
}
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async getTransfer(orderId: number) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `SELECT L.NUMPED as "orderId"
,L.DTTRANSF as "transferDate"
,L.NUMNOTA as "invoiceId"
,L.NUMTRANSVENDA as "transactionId"
,L.NUMCARANTERIOR as "oldShipment"
,L.NUMCARATUAL as "newShipment"
,L.MOTIVOTRANSF as "transferText"
,L.codmotivo||'-'||PCTABDEV.MOTIVO as "cause"
,L.codfunctransf||'-'||PCEMPR.NOME as "userName"
,L.rotinatransf as "program"
FROM PCLOGTRANSFNFCARREG L, PCTABDEV, PCEMPR
WHERE L.CODMOTIVO = PCTABDEV.coddevol (+)
AND L.CODFUNCTRANSF = PCEMPR.MATRICULA (+)
AND L.NUMTRANSVENDA IN ( SELECT PCPEDC.NUMTRANSVENDA FROM PCPEDC WHERE PCPEDC.NUMPED = ${orderId} )`;
const transferOrder = await queryRunner.manager.query(sql);
if ( transferOrder.length > 0 ) {
return transferOrder;
} else {
return null;
}
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async getStatusOrder(orderId: number) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
try {
const sql = `SELECT pcpedc.numped AS "orderId",
'Digitação pedido' AS "status",
TO_DATE (TO_CHAR(pcpedc.data, 'DD/MM/YYYY') || ' ' || pcpedc.hora || ':' || pcpedc.minuto,
'DD/MM/YYYY HH24:MI')
AS "statusDate",
pcpedc.codemitente || '-' || pcempr.nome "userName"
,NULL as "comments"
FROM pcpedc, pcempr
WHERE pcpedc.numped = ${orderId} AND pcpedc.codemitente = pcempr.matricula(+)
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Montagem de carga' AS "status",
TO_DATE (
TO_CHAR(pccarreg.datamon, 'DD/MM/YYYY')
|| ' '
|| pccarreg.horamon
|| ':'
|| pccarreg.minutomon,
'DD/MM/YYYY HH24:MI')
AS "statusDate",
pccarreg.codfuncmon || '-' || pcempr.nome "userName"
,NULL as "comments"
FROM pcpedc, pcempr, pccarreg
WHERE pcpedc.numped = ${orderId}
AND pccarreg.codfuncmon = pcempr.matricula(+)
AND pcpedc.numcar = pccarreg.numcar
AND pcpedc.numcar > 0
AND pccarreg.datamon is not null
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Emissão do mapa' AS "status",
CASE WHEN PCPEDC.DTEMISSAOMAPA IS NOT NULL THEN
TO_DATE (
TO_CHAR(pcpedc.dtemissaomapa, 'DD/MM/YYYY')
|| ' '
|| NVL(pcpedc.horaemissaomapa, '00')
|| ':'
|| nvl(pcpedc.minutoemissaomapa, '01'),
'DD/MM/YYYY HH24:MI') ELSE NULL END
AS "statusDate",
pcpedc.codfuncemissaomapa || '-' || pcempr.nome AS "userName"
,NULL as "comments"
FROM pcpedc, pcempr
WHERE pcpedc.numped = ${orderId}
AND pcpedc.codfuncemissaomapa = pcempr.matricula(+)
AND PCPEDC.DTEMISSAOMAPA IS NOT NULL
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Inicio de Separação' AS "status",
pcpedc.dtinicialsep as "statusDate",
pcpedc.codfuncsep || '-' || pcempr.nome "userName"
,NULL as "comments"
FROM pcpedc, pcempr
WHERE pcpedc.numped = ${orderId}
AND pcpedc.codfuncsep = pcempr.matricula(+)
AND PCPEDC.dtinicialsep IS NOT NULL
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Fim de Separação' AS "status",
pcpedc.dtfinalsep as "statusDate",
pcpedc.codfuncsep || '-' || pcempr.nome "userName"
,NULL as "comments"
FROM pcpedc, pcempr
WHERE pcpedc.numped = ${orderId} AND pcpedc.codfuncsep = pcempr.matricula(+)
and pcpedc.dtfinalsep is not null
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Inicio conferência' AS "status",
pcpedc.dtinicialcheckout AS "statusDate",
pcpedc.codfuncconf || '-' || pcempr.nome "userName"
,NULL as "comments"
FROM pcpedc, pcempr
WHERE pcpedc.numped = ${orderId}
AND pcpedc.codfuncconf = pcempr.matricula(+)
AND pcpedc.dtinicialcheckout IS NOT NULL
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Fim conferência' AS "status",
pcpedc.dtfinalcheckout AS "statusDate",
pcpedc.codfuncconf || '-' || pcempr.nome "userName"
,NULL as "comments"
FROM pcpedc, pcempr
WHERE pcpedc.numped = ${orderId}
AND pcpedc.codfuncconf = pcempr.matricula(+)
AND pcpedc.dtfinalcheckout IS NOT NULL
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Faturamento' AS "status",
TO_DATE (
TO_CHAR(pcpedc.dtfat, 'DD/MM/YYYY') || ' ' || pcpedc.horafat || ':' || pcpedc.minutofat,
'DD/MM/YYYY HH24:MI')
AS "statusDate",
pcempr.matricula || '-' || pcempr.nome "userName"
,NULL as "comments"
FROM pcpedc, pcempr, pccarreg, pcnfsaid
WHERE pcpedc.numped = ${orderId}
AND pcpedc.numcar = pccarreg.numcar
and pcpedc.numtransvenda = pcnfsaid.numtransvenda
AND nvl(pcnfsaid.codemitente, decode(pcpedc.numcar,0,-1,pccarreg.codfuncfat)) = pcempr.matricula(+)
AND pcpedc.dtfat IS NOT NULL
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Entrega' AS "status",
pcnfsaid.dtcanhoto AS "statusDate",
CASE WHEN PCNFSAID.NUMCAR > 0 THEN
pcnfsaid.codfunccanhoto || '-' || pcempr.nome
ELSE '' END "userName"
,NULL as "comments"
FROM pcpedc, pcnfsaid, pcempr, pccarreg
WHERE pcpedc.numped = ${orderId}
AND pcpedc.numtransvenda = pcnfsaid.numtransvenda
AND pcnfsaid.numcar = pccarreg.numcar (+)
AND pcnfsaid.codfunccanhoto = pcempr.matricula(+)
AND pcnfsaid.dtcanhoto IS NOT NULL
UNION ALL
SELECT pcpedc.numped AS "orderId",
'Transf entre carregamento' AS "status",
pclogtransfnfcarreg.dttransf AS "statusDate",
pclogtransfnfcarreg.codfunctransf || '-' || pcempr.nome "userName",
'ORIG: '||pclogtransfnfcarreg.numcaranterior || ' ->
DEST.: ' ||pclogtransfnfcarreg.numcaratual as "comments"
FROM pclogtransfnfcarreg, pcpedc, pcempr
WHERE pclogtransfnfcarreg.numnota = pcpedc.numnota (+)
AND pcpedc.numped = ${orderId}
AND pclogtransfnfcarreg.codfunctransf = pcempr.matricula(+)
ORDER BY 3`;
const statusOrder = await queryRunner.manager.query(sql);
if ( statusOrder.length > 0 ) {
return statusOrder;
} else {
return null;
}
} catch(e) {
console.log(e);
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async createInvoiceCheck(invoice: any) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
// TO_DATE('YYYY-MM-DDTHH24:MI:SS.000Z','${invoice.startDate}'),
// TO_DATE('YYYY-MM-DDTHH24:MI:SS.000Z','${invoice.endDate}'),
try {
const sqlSequence = 'SELECT ESSCONFERENCIANF.NEXTVAL as "id" FROM DUAL';
const dbSequence = await queryRunner.manager.query(sqlSequence);
const checkId = dbSequence[0].id;
const sql = `INSERT INTO ESTCONFERENCIANF ( ID, NUMTRANSVENDA, CODFILIAL, NUMNOTA, DTINICIO, DTFIM, CODFUNCCONF )
VALUES ( ${checkId}, ${invoice.transactionId}, ${invoice.storeId}, ${invoice.invoiceId},
TO_DATE(SUBSTR(REPLACE(REPLACE('${invoice.startDate}', 'T', ' '), 'Z', ''),1,18), 'YYYY-MM-DD HH24:MI:SS'),
TO_DATE(SUBSTR(REPLACE(REPLACE('${invoice.endDate}', 'T', ' '), 'Z', ''),1,18), 'YYYY-MM-DD HH24:MI:SS'),
${invoice.userId} )`;
await queryRunner.manager.query(sql);
for ( const item of invoice.itens ) {
const sqlItem = `INSERT INTO ESTCONFERENCIANFITENS ( IDCONF, NUMTRANSVENDA, CODPROD, NUMSEQ, QT, DTCONF )
VALUES ( ${checkId}, ${invoice.transactionId}, ${item.productId}, ${item.seq}, ${item.qt},
TO_DATE(SUBSTR(REPLACE(REPLACE('${item.confDate}', 'T', ' '), 'Z', ''),1,18), 'YYYY-MM-DD HH24:MI:SS') )`;
await queryRunner.manager.query(sqlItem);
}
await queryRunner.commitTransaction();
return { message: 'Conferência salva com sucesso!' }
} catch(erro) {
await queryRunner.rollbackTransaction();
console.log(erro);
throw new HttpException(erro.message, HttpStatus.BAD_REQUEST);
}
finally {
await queryRunner.release();
await dataSource.destroy();
}
}
}

View File

@@ -0,0 +1,215 @@
// src/modules/orders/infrastructure/repositories/orders.repository.ts
import { Injectable } from '@nestjs/common';
import { DataSource } from 'typeorm';
import { InjectDataSource } from '@nestjs/typeorm';
import { createOracleConfig } from '../../core/configs/typeorm.oracle.config';
import { FindOrdersDto } from '../dto/find-orders.dto';
@Injectable()
export class OrdersRepository {
constructor(
@InjectDataSource('oracle') private readonly dataSource: DataSource
) {}
async findOrders(query: FindOrdersDto): Promise<any[]> {
await this.dataSource.initialize();
const queryRunner = this.dataSource.createQueryRunner();
await queryRunner.connect();
try {
let sql = `SELECT PCPEDC.DATA as "createDate"
,PCPEDC.CODFILIAL || CASE WHEN PCPEDC.CODFILIALLOJA IS NOT NULL THEN
' - Pre-Box ('||PCPEDC.CODFILIALLOJA||')'
ELSE NULL END as "storeId"
,PCPEDC.NUMPED as "orderId"
,PCPEDC.CODCLI as "customerId"
,PCPEDC.CODCLI||' - '||PCCLIENT.CLIENTE as "customerName"
,PCPEDC.CODUSUR as "sellerId"
,PCPEDC.CODUSUR||' - '||PCUSUARI.NOME as "sellerName"
,PCSUPERV.NOME as "store"
,( SELECT CASE WHEN PCPEDI.TIPOENTREGA = 'EN' THEN 'Entrega ('||PCPEDI.TIPOENTREGA||')'
WHEN PCPEDI.TIPOENTREGA = 'EF' THEN 'Entrega Futura ('||PCPEDI.TIPOENTREGA||')'
WHEN PCPEDI.TIPOENTREGA = 'RP' THEN 'Retira Posterior ('||PCPEDI.TIPOENTREGA||')'
WHEN PCPEDI.TIPOENTREGA = 'RI' THEN 'Retira Imediata ('||PCPEDI.TIPOENTREGA||')'
ELSE 'Não Informado' END
FROM PCPEDI
WHERE PCPEDI.NUMPED = PCPEDC.NUMPED
AND ROWNUM = 1 ) as "deliveryType"
,CASE WHEN NVL(PCPEDC.CODENDENTCLI,0) = 0 THEN
( SELECT PCPRACA.CODPRACA||'-'||PCPRACA.PRACA
FROM PCPRACA
WHERE PCPRACA.CODPRACA = PCPEDC.CODPRACA )
ELSE ( SELECT PCPRACA.CODPRACA||'-'||PCPRACA.PRACA
FROM PCCLIENTENDENT, PCPRACA
WHERE PCCLIENTENDENT.CODCLI = PCPEDC.CODCLI
AND PCCLIENTENDENT.CODENDENTCLI = PCPEDC.CODENDENTCLI
AND PCCLIENTENDENT.CODPRACAENT = PCPRACA.CODPRACA ) END as "deliveryLocal"
,CASE WHEN NVL(PCPEDC.CODENDENTCLI,0) = 0 THEN
( SELECT PCROTAEXP.CODROTA||'-'||PCROTAEXP.DESCRICAO
FROM PCPRACA, PCROTAEXP
WHERE PCPRACA.CODPRACA = PCPEDC.CODPRACA
AND PCPRACA.ROTA = PCROTAEXP.CODROTA )
ELSE ( SELECT PCROTAEXP.CODROTA||'-'||PCROTAEXP.DESCRICAO
FROM PCCLIENTENDENT, PCPRACA, PCROTAEXP
WHERE PCCLIENTENDENT.CODCLI = PCPEDC.CODCLI
AND PCCLIENTENDENT.CODENDENTCLI = PCPEDC.CODENDENTCLI
AND PCCLIENTENDENT.CODPRACAENT = PCPRACA.CODPRACA
AND PCPRACA.ROTA = PCROTAEXP.CODROTA ) END as "masterDeliveryLocal"
,CASE WHEN PCPEDC.CONDVENDA = 1 THEN 'TV1 - Retira Imediata'
WHEN PCPEDC.CONDVENDA = 7 THEN 'TV7 - Faturamento'
WHEN PCPEDC.CONDVENDA = 8 THEN 'TV8 - Entrega (' ||
( SELECT PCPEDI.TIPOENTREGA FROM PCPEDI
WHERE PCPEDI.NUMPED = PCPEDC.NUMPED
AND ROWNUM = 1 ) ||')'
WHEN PCPEDC.CONDVENDA = 10 THEN 'TV10 - Transferência'
ELSE 'Outros' END as "orderType"
,CASE WHEN PCPEDC.POSICAO = 'P' THEN 'Pendente'
WHEN PCPEDC.POSICAO = 'B' THEN 'Bloqueado'
WHEN PCPEDC.POSICAO = 'L' THEN 'Liberado'
WHEN PCPEDC.POSICAO = 'M' THEN 'Montado'
WHEN PCPEDC.POSICAO = 'F' THEN 'Faturado'
WHEN PCPEDC.POSICAO = 'C' THEN 'Cancelado'
END as "status"
,CASE WHEN PCPEDC.CONDVENDA IN (1,7) THEN PCPEDC.VLATEND ELSE PCPEDC.VLTOTAL END as "amount"
,PCPEDC.DTENTREGA as "deliveryDate"
,CASE WHEN PCPEDC.tipoprioridadeentrega = 'B' THEN 'Baixa'
WHEN PCPEDC.TIPOPRIORIDADEENTREGA = 'M' THEN 'Média'
WHEN PCPEDC.TIPOPRIORIDADEENTREGA = 'A' THEN 'Alta'
ELSE 'Não Definido' END as "deliveryPriority"
,PCPEDC.NUMCAR as "shipmentId"
,PCPEDC.DTLIBERA as "releaseDate"
,PCPEDC.CODFUNCLIBERA as "releaseUser"
,PCPEDC.CODFUNCLIBERA||'-'||
(SELECT PCEMPR.NOME FROM PCEMPR WHERE PCEMPR.MATRICULA = PCPEDC.CODFUNCLIBERA) as "releaseUserName"
,PCCARREG.DTSAIDA as "shipmentDate"
,PCCARREG.DATAMON as "shipmentDateCreate"
,CASE WHEN PCPEDC.NUMCAR = 0 THEN NULL
ELSE PCCARREG.DTFECHA END as "shipmentCloseDate"
,PCPEDC.CODPLPAG as "paymentId"
,PCPLPAG.DESCRICAO as "paymentName"
,PCPEDC.CODCOB as "billingId"
,PCPEDC.CODCOB||'-'||
PCCOB.COBRANCA as "billingName"
,PCPEDC.DTFAT as "invoiceDate"
,PCPEDC.HORAFAT as "invoiceHour"
,PCPEDC.MINUTOFAT as "invoiceMinute"
,PCPEDC.NUMNOTA as "invoiceNumber"
,PCPEDC.MOTIVOPOSICAO as "BloqDescription"
,PCNFSAID.DTCANHOTO as "confirmDeliveryDate"
,PCPEDC.TOTPESO as "totalWeigth"
,CASE WHEN PCNFSAID.DTCANHOTO IS NOT NULL THEN 4
WHEN PCPEDC.POSICAO = 'F' THEN 3
WHEN PCPEDC.DTFINALSEP IS NOT NULL THEN 2
WHEN PCPEDC.POSICAO = 'M' THEN 1
WHEN PCPEDC.POSICAO IN ('L', 'P', 'B') THEN 0
ELSE 0 END as "processOrder"
,( SELECT COUNT(1) FROM PCPREST, PCNFSAID, PCPEDC PED_VGER
WHERE PCPREST.NUMTRANSVENDA = PCNFSAID.NUMTRANSVENDA
AND PCNFSAID.NUMTRANSVENDA = PED_VGER.NUMTRANSVENDA
AND PED_VGER.NUMPED = PCPEDC.NUMPEDENTFUT
AND PCPREST.DTPAG IS NULL
AND PCPREST.CODCOB = 'VGER' ) as "payment"
,MOTORISTA.MATRICULA || ' - ' || MOTORISTA.NOME as "driver"
,PCPEDC.NUMPEDENTFUT as "orderSaleId"
,PCVEICUL.DESCRICAO||' ( '|| PCVEICUL.PLACA||' )' as "carDescription"
,PCVEICUL.PLACA as "carIdentification"
,PCPEDC.CODFORNECFRETE||' - '||PCFORNEC.FORNECEDOR as "carrier"
,CASE WHEN (SELECT COUNT(1) FROM PCNFENT, PCFILIAL
WHERE PCFILIAL.CODIGO = PCPEDC.CODFILIAL
AND PCFILIAL.CODFORNEC = PCNFENT.CODFORNEC
AND PCNFENT.NUMNOTA = PCPEDC.NUMNOTA ) = 0
AND PCPEDC.CONDVENDA = 10
AND PCPEDC.POSICAO = 'F' THEN 'Em Trânsito'
WHEN PCPEDC.POSICAO = 'M'
AND PCPEDC.CONDVENDA = 10 THEN 'Em Separação'
WHEN PCPEDC.POSICAO IN ( 'L', 'P' )
AND PCPEDC.CONDVENDA = 10 THEN 'Aguardando Separação'
WHEN PCPEDC.CONDVENDA NOT IN ( 10 ) THEN NULL
ELSE 'Concluída' END as "statusTransfer"
,PCPEDC.CODFILIALLOJA as "storePreBox"
FROM PCPEDC, PCCLIENT, PCUSUARI, PCSUPERV, PCCOB, PCPLPAG, PCCARREG, PCNFSAID,
PCEMPR MOTORISTA, PCVEICUL, PCFORNEC
WHERE PCPEDC.CODCLI = PCCLIENT.CODCLI
AND PCPEDC.CODUSUR = PCUSUARI.CODUSUR
AND PCPEDC.CODPLPAG = PCPLPAG.CODPLPAG
AND PCPEDC.CODCOB = PCCOB.CODCOB
AND PCPEDC.CODSUPERVISOR = PCSUPERV.CODSUPERVISOR
AND PCPEDC.NUMTRANSVENDA = PCNFSAID.NUMTRANSVENDA (+)
AND PCPEDC.NUMCAR = PCCARREG.NUMCAR (+)
AND PCCARREG.CODMOTORISTA = MOTORISTA.MATRICULA (+)
AND PCCARREG.CODVEICULO = PCVEICUL.CODVEICULO (+)
AND PCPEDC.CODFORNECFRETE = PCFORNEC.CODFORNEC (+)`;
const conditions: string[] = [];
if (query.storeId) {
conditions.push(`AND PCPEDC.CODFILIAL = :storeId`);
}
if (query.storeStockId) {
conditions.push(`AND EXISTS(SELECT 1 FROM PCPEDI WHERE PCPEDI.NUMPED = PCPEDC.NUMPED AND PCPEDI.CODFILIALRETIRA = :storeStockId)`);
}
if (query.sellerId) {
conditions.push(`AND PCPEDC.CODUSUR = :sellerId`);
}
if (query.customerId) {
conditions.push(`AND PCPEDC.CODCLI = :customerId`);
}
if (query.billingId) {
conditions.push(`AND PCPEDC.CODCOB = :billingId`);
}
if (query.orderId) {
conditions.push(`AND (PCPEDC.NUMPED = :orderId OR PCPEDC.NUMPEDENTFUT = :orderId)`);
}
if (query.invoiceId) {
conditions.push(`AND PCPEDC.NUMNOTA = :invoiceId`);
}
if (query.productId) {
conditions.push(`AND EXISTS(SELECT 1 FROM PCPEDI WHERE PCPEDI.NUMPED = PCPEDC.NUMPED AND PCPEDI.CODPROD = :productId)`);
}
if (query.createDateIni) {
conditions.push(`AND PCPEDC.DATA >= TO_DATE(:createDateIni, 'YYYY-MM-DD')`);
}
if (query.createDateEnd) {
conditions.push(`AND PCPEDC.DATA <= TO_DATE(:createDateEnd, 'YYYY-MM-DD')`);
}
if (query.invoiceDateIni) {
conditions.push(`AND PCPEDC.DTFAT >= TO_DATE(:invoiceDateIni, 'YYYY-MM-DD')`);
}
if (query.invoiceDateEnd) {
conditions.push(`AND PCPEDC.DTFAT <= TO_DATE(:invoiceDateEnd, 'YYYY-MM-DD')`);
}
if (query.shippimentId) {
conditions.push(`AND PCPEDC.NUMCAR = :shippimentId`);
}
if (query.deliveryType) {
const types = query.deliveryType.split(',').map(t => `'${t}'`).join(',');
conditions.push(`AND EXISTS(SELECT 1 FROM PCPEDI WHERE PCPEDI.NUMPED = PCPEDC.NUMPED AND PCPEDI.TIPOENTREGA IN (${types}))`);
}
if (query.status) {
const statusList = query.status.split(',').map(s => `'${s}'`).join(',');
conditions.push(`AND PCPEDC.POSICAO IN (${statusList})`);
}
if (query.type) {
const types = query.type.split(',').map(t => `'${t}'`).join(',');
conditions.push(`AND PCPEDC.CONDVENDA IN (${types})`);
}
if (query.onlyPendentingTransfer === 'S') {
conditions.push(`
AND NOT EXISTS(SELECT 1 FROM PCNFENT, PCFILIAL
WHERE PCFILIAL.CODIGO = PCPEDC.CODFILIAL
AND PCFILIAL.CODFORNEC = PCNFENT.CODFORNEC
AND PCNFENT.NUMNOTA = PCPEDC.NUMNOTA)`);
}
sql += '\n' + conditions.join('\n');
sql += '\nAND ROWNUM < 5000';
const orders = await queryRunner.manager.query(sql);
return orders;
} finally {
await queryRunner.release();
await this.dataSource.destroy();
}
}
}