import { BadGatewayException, Injectable, InternalServerErrorException, NotAcceptableException, NotFoundException, UnprocessableEntityException, } from '@nestjs/common'; import { DatabaseService } from '../database/database.service'; import { EntregaDto } from './dto/orders.dto'; // Interfaces para tipagem dos dados interface NotaFiscal { CODFILIAL: string; DTSAIDA: Date | string; NUMPED: number; CHAVENFE: string; NUMNOTA: number; NUMTRANSVENDA: number; CODCLI: number; CLIENTE: string; CODUSUR: number; NOME: string; NUMITENS: number; DTCANHOTO: Date | string | null; DEVOL: string; CONDVENDA: number; } interface Produto { CODPROD: number; DESCRICAO: string; UNIDADE: string; CODAUXILIAR: string; MULTIPLO: number; URLIMAGEM: string; QT: number; } interface NotaFiscalComItens { CODFILIAL: string; DTSAIDA: Date | string; NUMPED: number; CHAVENFE: string; NUMNOTA: number; NUMTRANSVENDA: number; CODCLI: number; CLIENTE: string; CODUSUR: number; NOME: string; NUMITENS: number; DTCANHOTO: Date | string | null; itens: Produto[]; } // Interface para o resultado do banco de dados interface DatabaseResult { rows: any[]; rowsAffected?: number; } // Interface para o resultado da permissão interface PermissaoResult { CODUSUARIO: number; CODROTINA: number; ACESSO: string; } @Injectable() export class OrdersService { constructor(private readonly databaseService: DatabaseService) { } async getNotaFiscal(chaveNota: string): Promise { const sqlNotaFiscal = ` SELECT PCNFSAID.CODFILIAL, TO_CHAR(PCNFSAID.DTSAIDA, 'DD/MM/YYYY') AS DTSAIDA, PCNFSAID.NUMPED, PCNFSAID.CHAVENFE, PCNFSAID.NUMNOTA, PCNFSAID.NUMTRANSVENDA, PCNFSAID.CODCLI, PCCLIENT.CLIENTE, PCNFSAID.CODUSUR, PCUSUARI.NOME, PCNFSAID.NUMITENS, TO_CHAR(PCNFSAID.DTCANHOTO, 'DD/MM/YYYY') AS DTCANHOTO, NVL((SELECT 'S' FROM ESTPREDEVCLI WHERE ESTPREDEVCLI.NUMTRANSVENDA = PCNFSAID.NUMTRANSVENDA and rownum=1),'N') DEVOL, PCNFSAID.CONDVENDA FROM PCNFSAID, PCCLIENT, PCUSUARI WHERE PCNFSAID.CODCLI = PCCLIENT.CODCLI AND PCNFSAID.CODUSUR = PCUSUARI.CODUSUR AND PCNFSAID.DTCANCEL IS NULL AND PCNFSAID.CHAVENFE=:chaveNota`; const sqlProduto = ` SELECT PCMOV.CODPROD, PCPRODUT.DESCRICAO, PCPRODUT.UNIDADE, PCPRODUT.CODAUXILIAR, PCPRODUT.MULTIPLO, PCPRODUT.URLIMAGEM, SUM(PCMOV.QT) QT FROM PCMOV, PCPRODUT WHERE PCMOV.CODPROD = PCPRODUT.CODPROD AND PCMOV.NUMTRANSVENDA = :transacao GROUP BY PCMOV.CODPROD, PCPRODUT.DESCRICAO, PCPRODUT.UNIDADE, PCPRODUT.CODAUXILIAR, PCPRODUT.MULTIPLO, PCPRODUT.URLIMAGEM`; try { const result = (await this.databaseService.execute(sqlNotaFiscal, [ chaveNota, ])) as DatabaseResult; if (!result || !result.rows || result.rows.length === 0) { throw new NotFoundException('Nota Fiscal não encontrada'); } const notaFiscal = result.rows[0] as NotaFiscal; if (notaFiscal.CONDVENDA !== 8) { throw new UnprocessableEntityException( 'Nota fiscal não é do tipo de Entrega', ); } if (notaFiscal.DEVOL === 'S') { throw new NotAcceptableException('Nota fiscal ja feito devolução'); } if (notaFiscal.DTCANHOTO !== null) { throw new BadGatewayException('Nota Fiscal entregue ao cliente!'); } const itensResult = (await this.databaseService.execute(sqlProduto, [ notaFiscal.NUMTRANSVENDA, ])) as DatabaseResult; const itens = itensResult.rows as Produto[]; const notaFiscalComItens: NotaFiscalComItens = { CODFILIAL: notaFiscal.CODFILIAL, DTSAIDA: notaFiscal.DTSAIDA, NUMPED: notaFiscal.NUMPED, CHAVENFE: notaFiscal.CHAVENFE, NUMNOTA: notaFiscal.NUMNOTA, NUMTRANSVENDA: notaFiscal.NUMTRANSVENDA, CODCLI: notaFiscal.CODCLI, CLIENTE: notaFiscal.CLIENTE, CODUSUR: notaFiscal.CODUSUR, NOME: notaFiscal.NOME, NUMITENS: notaFiscal.NUMITENS, DTCANHOTO: notaFiscal.DTCANHOTO, itens: itens.map((item) => { return { CODPROD: item.CODPROD, DESCRICAO: item.DESCRICAO, UNIDADE: item.UNIDADE, CODAUXILIAR: item.CODAUXILIAR, MULTIPLO: item.MULTIPLO, QT: item.QT, URLIMAGEM: item.URLIMAGEM ? item.URLIMAGEM.split(';')[0].replace( 'http://167.249.211.178:8001', 'http://10.1.1.191', ) : '', }; }), }; return notaFiscalComItens; } catch (error) { throw new InternalServerErrorException( 'Erro ao buscar nota fiscal', error instanceof Error ? error.message : 'Erro desconhecido', ); } } async getPermissao(idUsuario: number, codRotina: number): Promise { const sqlPermissao = ` SELECT PCCONTRO.CODUSUARIO, PCCONTRO.CODROTINA, PCCONTRO.ACESSO FROM PCCONTRO WHERE PCCONTRO.CODUSUARIO = :idUsuario AND PCCONTRO.CODROTINA = :codRotina AND PCCONTRO.ACESSO = 'S' `; try { const result = (await this.databaseService.execute(sqlPermissao, [ idUsuario, codRotina, ])) as DatabaseResult; if (!result || !result.rows || result.rows.length === 0) { throw new NotFoundException( 'Usuario sem permissao para acessar notas fiscais', ); } const permissao = result.rows[0] as PermissaoResult; return { idUsuario: permissao.CODUSUARIO, codRotina: permissao.CODROTINA, acesso: permissao.ACESSO, }; } catch (error) { throw new InternalServerErrorException( 'Erro ao buscar permissao', error instanceof Error ? error.message : 'Erro desconhecido', ); } } async updateRegistro( chaveNota: string, codusuario: number, entrega: EntregaDto, ): Promise { const sqlUpdate = ` UPDATE PCNFSAID SET CODFUNCCANHOTO = :codusuario, DTCANHOTO = TRUNC(SYSDATE) WHERE CHAVENFE = :chaveNota `; const sqlInsertEntrega = `INSERT INTO ESTENTREGAS (CODSAIDA, NUMTRANSVENDA, DATA, DOCUMENTORECEBEDOR, NOMERECEBEDOR) VALUES (0, :NUMTRANSVENDA, SYSDATE, :DOCUMENTO, :RECEBEDOR)`; const seleInsertEntregaImagem = `INSERT INTO ESTENTREGASIMAGENS (CODSAIDA, NUMTRANSVENDA, TIPO, URL) VALUES (0,:NUMTRANSVENDA,:TIPO, :URLIMAGEM)`; try { const result = (await this.databaseService.execute(sqlUpdate, [ codusuario, chaveNota, ])) as DatabaseResult; // Verificar se algum registro foi afetado if (result.rowsAffected === 0) { throw new NotFoundException( 'Nenhum registro encontrado para atualizar', ); } const resultEntregas = (await this.databaseService.execute( sqlInsertEntrega, [entrega.NUMTRANSVENDA, entrega.DOCUMENTO, entrega.RECEBEDOR], )) as DatabaseResult; if (resultEntregas.rowsAffected === 0) { throw new NotFoundException( 'Nenhum registro de entrega encontrado para inserir', ); } for (const imagem of entrega.IMAGENS) { const resultImagem = (await this.databaseService.execute( seleInsertEntregaImagem, [entrega.NUMTRANSVENDA, imagem.TIPO, imagem.URLIMAGEM], )) as DatabaseResult; if (resultImagem.rowsAffected === 0) { throw new NotFoundException( 'Nenhum registro de imagem de entrega encontrado para inserir', ); } } return { message: 'Registro atualizado com sucesso!', success: true, rowsAffected: result.rowsAffected, }; } catch (error) { if (error instanceof NotFoundException) { throw error; } throw new InternalServerErrorException( 'Erro ao atualizar registro', error instanceof Error ? error.message : 'Erro desconhecido', ); } } }