import { Injectable, HttpException, HttpStatus } from '@nestjs/common'; import { EstLogTransferFilterDto, EstLogTransferResponseDto, } from '../dto/estlogtransfer.dto'; import { DataSource } from 'typeorm'; import { InjectDataSource } from '@nestjs/typeorm'; import { FindOrdersDto } from '../dto/find-orders.dto'; import { OrderItemDto } from '../dto/OrderItemDto'; import { CutItemDto } from '../dto/CutItemDto'; import { OrderDeliveryDto } from '../dto/OrderDeliveryDto'; import { OrderTransferDto } from '../dto/OrderTransferDto'; import { OrderStatusDto } from '../dto/OrderStatusDto'; import { InvoiceCheckDto } from '../dto/invoice-check.dto'; import { LeadtimeDto } from '../dto/leadtime.dto'; import { MarkData } from '../interface/markdata'; import { DeliveryCompletedQuery } from '../dto/delivery-completed-query.dto'; import { DeliveryCompleted } from '../dto/delivery-completed.dto'; @Injectable() export class OrdersRepository { constructor( @InjectDataSource('oracle') private readonly oracleDataSource: DataSource, @InjectDataSource('postgres') private readonly postgresDataSource: DataSource, ) {} /** * Busca log de transferência por ID do pedido * @param orderId - ID do pedido * @param filters - Filtros opcionais para a consulta * @returns Dados do log de transferência ou null se não encontrado */ async estlogtransfer( orderId: number, filters?: EstLogTransferFilterDto, ): Promise { if (!orderId || orderId <= 0) { throw new HttpException('OrderId inválido', HttpStatus.BAD_REQUEST); } let sql = ` SELECT E.DTTRANSF, E.CODFILIAL, E.CODFILIALDEST, E.NUMPEDLOJA, E.NUMPEDTRANSF, E.CODFUNCTRANSF, E.NUMPEDRCATRANSF, CASE WHEN P.POSICAO = 'F' AND P.CONDVENDA = 10 AND (SELECT COUNT(1) FROM PCNFENT, PCFILIAL WHERE PCFILIAL.CODIGO = P.CODFILIAL AND PCFILIAL.CODFORNEC = PCNFENT.CODFORNEC AND PCNFENT.NUMNOTA = P.NUMNOTA) = 0 AND P.CONDVENDA = 10 AND P.POSICAO = 'F' THEN 'Em Trânsito' WHEN P.POSICAO = 'M' AND P.CONDVENDA = 10 THEN 'Em Separação' WHEN P.POSICAO IN ( 'L', 'P' ) AND P.CONDVENDA = 10 THEN 'Aguardando Separação' WHEN P.CONDVENDA NOT IN ( 10 ) THEN NULL ELSE 'Concluída' END as "statusTransfer" FROM SEVEN.ESTLOGTRANSFCD E LEFT JOIN PCPEDC P ON (E.NUMPEDTRANSF IS NOT NULL AND E.NUMPEDTRANSF = P.NUMPED) OR (E.NUMPEDTRANSF IS NULL AND E.NUMPEDLOJA = P.NUMPED) WHERE E.NUMPEDLOJA = :orderId `; const parameters: any[] = [orderId]; if (filters?.dttransf) { sql += ` AND DTTRANSF = TO_DATE(:dttransf, 'YYYY-MM-DD')`; parameters.push(filters.dttransf); } if (filters?.codfilial) { sql += ` AND CODFILIAL = :codfilial`; parameters.push(filters.codfilial); } if (filters?.codfilialdest) { sql += ` AND CODFILIALDEST = :codfilialdest`; parameters.push(filters.codfilialdest); } if (filters?.numpedloja) { sql += ` AND NUMPEDLOJA = :numpedloja`; parameters.push(filters.numpedloja); } if (filters?.numpedtransf) { sql += ` AND NUMPEDTRANSF = :numpedtransf`; parameters.push(filters.numpedtransf); } sql += ` ORDER BY DTTRANSF DESC`; const result = await this.oracleDataSource.query(sql, parameters); return result.length > 0 ? result : null; } /** * Busca logs de transferência com filtros (sem especificar pedido específico) * @param filters - Filtros opcionais para a consulta * @returns Dados dos logs de transferência ou null se não encontrado */ async estlogtransfers( filters?: EstLogTransferFilterDto, ): Promise { let sql = ` SELECT E.DTTRANSF, E.CODFILIAL, E.CODFILIALDEST, E.NUMPEDLOJA, E.NUMPEDTRANSF, E.CODFUNCTRANSF, E.NUMPEDRCATRANSF, CASE WHEN P.POSICAO = 'F' AND P.CONDVENDA = 10 AND (SELECT COUNT(1) FROM PCNFENT, PCFILIAL WHERE PCFILIAL.CODIGO = P.CODFILIAL AND PCFILIAL.CODFORNEC = PCNFENT.CODFORNEC AND PCNFENT.NUMNOTA = P.NUMNOTA) = 0 AND P.CONDVENDA = 10 AND P.POSICAO = 'F' THEN 'Em Trânsito' WHEN P.POSICAO = 'M' AND P.CONDVENDA = 10 THEN 'Em Separação' WHEN P.POSICAO IN ( 'L', 'P' ) AND P.CONDVENDA = 10 THEN 'Aguardando Separação' WHEN P.CONDVENDA NOT IN ( 10 ) THEN NULL ELSE 'Concluída' END as "statusTransfer" FROM SEVEN.ESTLOGTRANSFCD E LEFT JOIN PCPEDC P ON (E.NUMPEDTRANSF IS NOT NULL AND E.NUMPEDTRANSF = P.NUMPED) OR (E.NUMPEDTRANSF IS NULL AND E.NUMPEDLOJA = P.NUMPED) WHERE 1=1 `; const parameters: any[] = []; if (filters?.dttransf) { sql += ` AND DTTRANSF = TO_DATE(:dttransf, 'YYYY-MM-DD')`; parameters.push(filters.dttransf); } if (filters?.dttransfIni && filters?.dttransfEnd) { sql += ` AND DTTRANSF BETWEEN TO_DATE(:dttransfIni, 'YYYY-MM-DD') AND TO_DATE(:dttransfEnd, 'YYYY-MM-DD')`; parameters.push(filters.dttransfIni, filters.dttransfEnd); } else if (filters?.dttransfIni) { sql += ` AND DTTRANSF >= TO_DATE(:dttransfIni, 'YYYY-MM-DD')`; parameters.push(filters.dttransfIni); } else if (filters?.dttransfEnd) { sql += ` AND DTTRANSF <= TO_DATE(:dttransfEnd, 'YYYY-MM-DD')`; parameters.push(filters.dttransfEnd); } if (filters?.codfilial) { sql += ` AND CODFILIAL = :codfilial`; parameters.push(filters.codfilial); } if (filters?.codfilialdest) { sql += ` AND CODFILIALDEST = :codfilialdest`; parameters.push(filters.codfilialdest); } if (filters?.numpedloja) { sql += ` AND NUMPEDLOJA = :numpedloja`; parameters.push(filters.numpedloja); } if (filters?.numpedtransf) { sql += ` AND NUMPEDTRANSF = :numpedtransf`; parameters.push(filters.numpedtransf); } sql += ` ORDER BY DTTRANSF ASC`; const result = await this.oracleDataSource.query(sql, parameters); return result.length > 0 ? result : null; } /** * Retorna dados de um pedido específico cruzados com seu fechamento de caixa, * filtrados apenas pelo número do pedido. Retorna apenas um registro. */ async findorderbymark(orderId: number): Promise { const sql = ` SELECT p.MARCA, p.CODMARCA, p.ATIVO FROM PCMARCA p WHERE p.CODMARCA = :orderId `; const results = await this.oracleDataSource.query(sql, [orderId]); return results[0] || null; } async findOrderWithCheckoutByOrder(orderId: number): Promise { const sql = ` SELECT e1.NOME AS NOME_FUNCIONARIO_CAIXA, r.DTCXMOTHHMMSS AS DATA_FECHAMENTO, e2.NOME AS NOME_ACERTO_MOTORISTA, r.NUMCHECKOUT AS CAIXA FROM PCPREST r, PCEMPR e1, PCEMPR e2, PCPEDC p WHERE p.NUMPED = r.NUMPED AND e1.MATRICULA = r.CODFUNCCHECKOUT AND e2.MATRICULA = r.CODFUNCCXMOT AND p.NUMPED = :1 `; const results = await this.oracleDataSource.query(sql, [orderId]); return results[0] || null; } async findOrders(query: FindOrdersDto): Promise { const queryRunner = this.oracleDataSource.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.CODUSUR2 as "codusur2" ,PCPEDC.CODUSUR2||' - '||PCUSUARI2.NOME as "codusur2Name" ,PCPEDC.CODUSUR3 as "partnerId" ,PCPEDC.HORAFAT as "HORA FATURAMENTO" ,PCPEDC.MINUTOFAT as "MINUTO FATURAMENTO" ,ESTPARCEIRO.NOME as "partnerName" ,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.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" ,CASE WHEN PCNFSAID.DTCANHOTO IS NOT NULL THEN 'ENTREGA CONFIRMADA' WHEN PCPEDC.POSICAO = 'F' THEN 'FATURADO' WHEN PCPEDC.DTFINALSEP IS NOT NULL THEN 'SEPARADO' WHEN PCPEDC.POSICAO = 'M' THEN 'MONTADO' WHEN PCPEDC.POSICAO = 'C' THEN 'CANCELADO' WHEN PCPEDC.POSICAO = 'L' THEN 'AGUARDANDO SEPARAÇÃO' WHEN PCPEDC.POSICAO = 'P' THEN 'ESTOQUE PENDENTE' WHEN PCPEDC.POSICAO = 'B' THEN 'BLOQUEIO FINANCEIRO' ELSE 'NÃO DEFINIDO' END as "status" ,( 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 'CONCLUIDA' END as "statusTransfer" ,PCPEDC.CODFILIALLOJA as "storePreBox" ,(SELECT MAX(EST.NUMPEDTRANSF) FROM SEVEN.ESTLOGTRANSFCD EST WHERE EST.NUMPEDLOJA = PCPEDC.NUMPED) as "transferOrderNumber" ,CASE WHEN NVL(PCPEDCTEMP.DTENTREGAORIG, PCPEDC.DTENTREGA) < PCPEDC.DTENTREGA THEN 'ENTREGA AGENDADA' ELSE 'ENTREGA NORMAL' END as "schedulerDelivery" ,NVL(PCNFSAID.CODEMITENTE, DECODE(PCPEDC.NUMCAR,0,-1,PCCARREG.CODFUNCFAT)) as "fatUserCode" ,(SELECT PCEMPR.NOME FROM PCEMPR WHERE PCEMPR.MATRICULA = NVL(PCNFSAID.CODEMITENTE, DECODE(PCPEDC.NUMCAR,0,-1,PCCARREG.CODFUNCFAT))) as "fatUserName" ,CASE WHEN NVL(PCNFSAID.CODEMITENTE, DECODE(PCPEDC.NUMCAR,0,-1,PCCARREG.CODFUNCFAT)) IS NOT NULL AND NVL(PCNFSAID.CODEMITENTE, DECODE(PCPEDC.NUMCAR,0,-1,PCCARREG.CODFUNCFAT)) != -1 THEN NVL(PCNFSAID.CODEMITENTE, DECODE(PCPEDC.NUMCAR,0,-1,PCCARREG.CODFUNCFAT)) || '-' || (SELECT PCEMPR.NOME FROM PCEMPR WHERE PCEMPR.MATRICULA = NVL(PCNFSAID.CODEMITENTE, DECODE(PCPEDC.NUMCAR,0,-1,PCCARREG.CODFUNCFAT))) ELSE NULL END as "fatUserDescription" ,PCPEDC.CODEMITENTE as "codEmitente" ,PCPEDC.CODEMITENTE as "emitenteMatricula" ,(SELECT PCEMPR.NOME FROM PCEMPR WHERE PCEMPR.MATRICULA = PCPEDC.CODEMITENTE) as "emitenteNome" FROM PCPEDC, PCCLIENT, PCUSUARI, PCUSUARI PCUSUARI2, PCSUPERV, PCCOB, PCPLPAG, PCCARREG, PCNFSAID, PCEMPR MOTORISTA, PCVEICUL, PCFORNEC, PCPEDCTEMP, PCPEDI, PCPRODUT, PCMARCA, ESTPARCEIRO WHERE PCPEDC.CODCLI = PCCLIENT.CODCLI AND PCPEDC.CODUSUR = PCUSUARI.CODUSUR AND PCPEDC.CODUSUR2 = PCUSUARI2.CODUSUR (+) AND PCPEDC.CODPLPAG = PCPLPAG.CODPLPAG AND PCPEDC.CODCOB = PCCOB.CODCOB AND PCPEDC.NUMPED = PCPEDCTEMP.NUMPED (+) 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 (+) AND PCPEDI.NUMPED = PCPEDC.NUMPED AND PCPEDI.CODPROD = PCPRODUT.CODPROD AND PCPRODUT.CODMARCA = PCMARCA.CODMARCA (+) AND PCPEDC.CODUSUR3 = ESTPARCEIRO.ID (+)`; const conditions: string[] = []; if (query.codfilial) { const filiais = query.codfilial .split(',') .map((f) => f.trim()) .filter((f) => f); if (filiais.length === 1) { conditions.push(`AND PCPEDC.CODFILIAL = :storeId`); } else { const filiaisList = filiais.join(','); conditions.push(`AND PCPEDC.CODFILIAL IN (${filiaisList})`); } } if (query.filialretira) { conditions.push( `AND EXISTS(SELECT 1 FROM PCPEDI WHERE PCPEDI.NUMPED = PCPEDC.NUMPED AND PCPEDI.CODFILIALRETIRA = :storeStockId)`, ); } if (query.sellerId) { const sellerIds = query.sellerId .split(',') .map((s) => s.trim()) .filter((s) => s) .join(','); conditions.push(`AND PCPEDC.CODUSUR IN (${sellerIds})`); } if (query.customerId) { conditions.push(`AND PCPEDC.CODCLI = :customerId`); } if (query.billingId) { conditions.push(`AND PCPEDC.CODCOB = :billingId`); } if (query.partnerId) { conditions.push(`AND PCPEDC.CODUSUR3 = :partnerId`); } if (query.codusur2) { const codusur2List = query.codusur2 .split(',') .map((c) => c.trim()) .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(',')})`; conditions.push(codusur2Condition); } 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.carrier) { conditions.push(`AND PCPEDC.CODFORNECFRETE = :carrier`); } if (query.markId) { conditions.push(`AND PCMARCA.CODMARCA = :markId`); } if (query.markName) { conditions.push( `AND UPPER(PCMARCA.MARCA) LIKE UPPER('%' || :markName || '%')`, ); } if (query.hasPreBox === true) { conditions.push( `AND EXISTS (SELECT 1 FROM SEVEN.ESTLOGTRANSFCD WHERE NUMPEDLOJA = PCPEDC.NUMPED)`, ); } if (query.preBoxFilial) { conditions.push(`AND PCPEDC.CODFILIALLOJA = :preBoxFilial`); } if (query.transferDestFilial) { conditions.push(`AND PCPEDC.CODFILIAL = :transferDestFilial`); } if (query.transferDateIni && query.transferDateEnd) { conditions.push(`AND EXISTS ( SELECT 1 FROM SEVEN.ESTLOGTRANSFCD WHERE NUMPEDLOJA = PCPEDC.NUMPED AND DTTRANSF BETWEEN TO_DATE(:transferDateIni, 'YYYY-MM-DD') AND TO_DATE(:transferDateEnd, 'YYYY-MM-DD') )`); } else if (query.transferDateIni) { conditions.push(`AND EXISTS ( SELECT 1 FROM SEVEN.ESTLOGTRANSFCD WHERE NUMPEDLOJA = PCPEDC.NUMPED AND DTTRANSF >= TO_DATE(:transferDateIni, 'YYYY-MM-DD') )`); } else if (query.transferDateEnd) { conditions.push(`AND EXISTS ( SELECT 1 FROM SEVEN.ESTLOGTRANSFCD WHERE NUMPEDLOJA = PCPEDC.NUMPED AND DTTRANSF <= TO_DATE(:transferDateEnd, 'YYYY-MM-DD') )`); } 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.onlyPendingTransfer === true) { 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)`); } if (query.statusTransfer) { const statusTransferList = query.statusTransfer .split(',') .map((s) => s.trim()); const statusConditions = statusTransferList .map((status) => { switch (status) { case 'Em Trânsito': return `(PCPEDC.CONDVENDA = 10 AND PCPEDC.POSICAO = 'F' AND (SELECT COUNT(1) FROM PCNFENT, PCFILIAL WHERE PCFILIAL.CODIGO = PCPEDC.CODFILIAL AND PCFILIAL.CODFORNEC = PCNFENT.CODFORNEC AND PCNFENT.NUMNOTA = PCPEDC.NUMNOTA) = 0)`; case 'Em Separação': return `(PCPEDC.CONDVENDA = 10 AND PCPEDC.POSICAO = 'M')`; case 'Aguardando Separação': return `(PCPEDC.CONDVENDA = 10 AND PCPEDC.POSICAO IN ('L', 'P'))`; case 'Concluída': return `(PCPEDC.CONDVENDA = 10 AND (SELECT COUNT(1) FROM PCNFENT, PCFILIAL WHERE PCFILIAL.CODIGO = PCPEDC.CODFILIAL AND PCFILIAL.CODFORNEC = PCNFENT.CODFORNEC AND PCNFENT.NUMNOTA = PCPEDC.NUMNOTA) > 0)`; default: return null; } }) .filter((condition) => condition !== null); if (statusConditions.length > 0) { conditions.push(`AND (${statusConditions.join(' OR ')})`); } } sql += '\n' + conditions.join('\n'); sql += '\nGROUP BY PCPEDC.DATA, PCPEDC.CODFILIAL, PCPEDC.CODFILIALLOJA, PCPEDC.NUMPED, PCPEDC.CODCLI, PCPEDC.CODENDENTCLI, PCPEDC.CODPRACA, PCPEDC.CODUSUR, PCPEDC.CODUSUR2, PCPEDC.CODUSUR3, PCPEDC.CODSUPERVISOR, PCPEDC.CONDVENDA, PCPEDC.VLATEND, PCPEDC.VLTOTAL, PCPEDC.DTENTREGA, PCPEDC.TIPOPRIORIDADEENTREGA, PCPEDC.NUMCAR, PCPEDC.DTLIBERA, PCPEDC.CODFUNCLIBERA, PCPEDC.NUMTRANSVENDA, PCPEDC.CODPLPAG, PCPEDC.CODCOB, PCPEDC.DTFAT, PCPEDC.HORAFAT, PCPEDC.MINUTOFAT, PCPEDC.NUMNOTA, PCPEDC.MOTIVOPOSICAO, PCPEDC.TOTPESO, PCPEDC.POSICAO, PCPEDC.DTFINALSEP, PCPEDC.NUMPEDENTFUT, PCPEDC.CODFORNECFRETE, PCPEDC.CODEMITENTE, PCCLIENT.CLIENTE, PCUSUARI.NOME, PCUSUARI2.NOME, PCSUPERV.NOME, PCCARREG.DTSAIDA, PCCARREG.DATAMON, PCCARREG.DTFECHA, PCCARREG.CODFUNCFAT, PCNFSAID.CODEMITENTE, PCPLPAG.DESCRICAO, PCCOB.COBRANCA, PCNFSAID.DTCANHOTO, MOTORISTA.MATRICULA, MOTORISTA.NOME, PCVEICUL.DESCRICAO, PCVEICUL.PLACA, PCFORNEC.FORNECEDOR, PCPEDCTEMP.DTENTREGAORIG, ESTPARCEIRO.NOME'; sql += '\nORDER BY PCPEDC.NUMPED DESC'; sql += '\nFETCH FIRST 5000 ROWS ONLY'; const parameters: any = {}; // Add parameters for bind variables if (query.codfilial) { const filiais = query.codfilial .split(',') .map((f) => f.trim()) .filter((f) => f); if (filiais.length === 1) { parameters.storeId = filiais[0]; } } if (query.filialretira) { parameters.storeStockId = query.filialretira; } if (query.customerId) { parameters.customerId = query.customerId; } if (query.billingId) { parameters.billingId = query.billingId; } if (query.partnerId) { parameters.partnerId = query.partnerId; } if (query.codusur2) { const codusur2List = query.codusur2 .split(',') .map((c) => c.trim()) .filter((c) => c) .map((c) => Number(c)) .filter((c) => !isNaN(c)); if (codusur2List.length === 1) { parameters.codusur2 = codusur2List[0]; } } if (query.orderId) { parameters.orderId = query.orderId; } if (query.invoiceId) { parameters.invoiceId = query.invoiceId; } if (query.hour) { parameters.hour = query.hour; } if (query.minute) { parameters.minute = query.minute; } if (query.productId) { parameters.productId = query.productId; } if (query.createDateIni) { parameters.createDateIni = query.createDateIni; } if (query.createDateEnd) { parameters.createDateEnd = query.createDateEnd; } if (query.invoiceDateIni) { parameters.invoiceDateIni = query.invoiceDateIni; } if (query.invoiceDateEnd) { parameters.invoiceDateEnd = query.invoiceDateEnd; } if (query.shippimentId) { parameters.shippimentId = query.shippimentId; } if (query.carrier) { parameters.carrier = query.carrier; } if (query.markId) { parameters.markId = query.markId; } if (query.markName) { parameters.markName = query.markName; } // Novos parâmetros para filtros de transferência if (query.preBoxFilial) { parameters.preBoxFilial = query.preBoxFilial; } if (query.transferDestFilial) { parameters.transferDestFilial = query.transferDestFilial; } if (query.transferDateIni) { parameters.transferDateIni = query.transferDateIni; } if (query.transferDateEnd) { parameters.transferDateEnd = query.transferDateEnd; } const orders = await queryRunner.manager.query(sql, parameters); return orders; } finally { await queryRunner.release(); } } /** * Busca pedidos por data de entrega com filtros específicos */ async findOrdersByDeliveryDate(query: any): Promise { const queryRunner = this.oracleDataSource.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.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" ,CASE WHEN PCNFSAID.DTCANHOTO IS NOT NULL THEN 'ENTREGA CONFIRMADA' WHEN PCPEDC.POSICAO = 'F' THEN 'FATURADO' WHEN PCPEDC.DTFINALSEP IS NOT NULL THEN 'SEPARADO' WHEN PCPEDC.POSICAO = 'M' THEN 'MONTADO' WHEN PCPEDC.POSICAO = 'L' THEN 'AGUARDANDO SEPARAÇÃO' WHEN PCPEDC.POSICAO = 'P' THEN 'ESTOQUE PENDENTE' WHEN PCPEDC.POSICAO = 'B' THEN 'BLOQUEIO FINANCEIRO' ELSE 'NÃO DEFINIDO' END as "status" ,( 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" ,CASE WHEN NVL(PCPEDCTEMP.DTENTREGAORIG, PCPEDC.DTENTREGA) < PCPEDC.DTENTREGA THEN 'ENTREGA AGENDADA' ELSE 'ENTREGA NORMAL' END as "schedulerDelivery" FROM PCPEDC, PCCLIENT, PCUSUARI, PCSUPERV, PCCOB, PCPLPAG, PCCARREG, PCNFSAID, PCEMPR MOTORISTA, PCVEICUL, PCFORNEC, PCPEDCTEMP, PCPEDI, PCPRODUT, PCMARCA WHERE PCPEDC.CODCLI = PCCLIENT.CODCLI AND PCPEDC.CODUSUR = PCUSUARI.CODUSUR AND PCPEDC.CODPLPAG = PCPLPAG.CODPLPAG AND PCPEDC.CODCOB = PCCOB.CODCOB AND NVL(NVL(PCPEDC.NUMPEDENTFUT, PCPEDC.NUMPEDTV1), PCPEDC.NUMPED) = PCPEDCTEMP.NUMPED (+) 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 (+) AND PCPEDI.NUMPED = PCPEDC.NUMPED AND PCPEDI.CODPROD = PCPRODUT.CODPROD AND PCPRODUT.CODMARCA = PCMARCA.CODMARCA (+)`; const conditions: string[] = []; // Filtros específicos para data de entrega if (query.deliveryDateIni) { conditions.push( `AND PCPEDC.DTENTREGA >= TO_DATE(:deliveryDateIni, 'YYYY-MM-DD')`, ); } if (query.deliveryDateEnd) { conditions.push( `AND PCPEDC.DTENTREGA <= TO_DATE(:deliveryDateEnd, 'YYYY-MM-DD')`, ); } // Filtros adicionais if (query.codfilial) { const filiais = query.codfilial .split(',') .map((f) => f.trim()) .filter((f) => f); if (filiais.length === 1) { conditions.push(`AND PCPEDC.CODFILIAL = :storeId`); } else { const filiaisList = filiais.join(','); conditions.push(`AND PCPEDC.CODFILIAL IN (${filiaisList})`); } } if (query.sellerId) { const sellerIds = query.sellerId .split(',') .map((s) => s.trim()) .filter((s) => s) .join(','); conditions.push(`AND PCPEDC.CODUSUR IN (${sellerIds})`); } if (query.customerId) { conditions.push(`AND PCPEDC.CODCLI = :customerId`); } if (query.orderId) { conditions.push( `AND (PCPEDC.NUMPED = :orderId OR PCPEDC.NUMPEDENTFUT = :orderId)`, ); } 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.markId) { conditions.push(`AND PCMARCA.CODMARCA = :markId`); } if (query.markName) { conditions.push( `AND UPPER(PCMARCA.MARCA) LIKE UPPER('%' || :markName || '%')`, ); } if (query.hasPreBox === true) { conditions.push( `AND EXISTS (SELECT 1 FROM SEVEN.ESTLOGTRANSFCD WHERE NUMPEDLOJA = PCPEDC.NUMPED)`, ); } if (query.statusTransfer) { const statusTransferList = query.statusTransfer .split(',') .map((s) => s.trim()); const statusConditions = statusTransferList .map((status) => { switch (status) { case 'Em Trânsito': return `(PCPEDC.CONDVENDA = 10 AND PCPEDC.POSICAO = 'F' AND (SELECT COUNT(1) FROM PCNFENT, PCFILIAL WHERE PCFILIAL.CODIGO = PCPEDC.CODFILIAL AND PCFILIAL.CODFORNEC = PCNFENT.CODFORNEC AND PCNFENT.NUMNOTA = PCPEDC.NUMNOTA) = 0)`; case 'Em Separação': return `(PCPEDC.CONDVENDA = 10 AND PCPEDC.POSICAO = 'M')`; case 'Aguardando Separação': return `(PCPEDC.CONDVENDA = 10 AND PCPEDC.POSICAO IN ('L', 'P'))`; case 'Concluída': return `(PCPEDC.CONDVENDA = 10 AND (SELECT COUNT(1) FROM PCNFENT, PCFILIAL WHERE PCFILIAL.CODIGO = PCPEDC.CODFILIAL AND PCFILIAL.CODFORNEC = PCNFENT.CODFORNEC AND PCNFENT.NUMNOTA = PCPEDC.NUMNOTA) > 0)`; default: return null; } }) .filter((condition) => condition !== null); if (statusConditions.length > 0) { conditions.push(`AND (${statusConditions.join(' OR ')})`); } } sql += '\n' + conditions.join('\n'); sql += '\nAND ROWNUM < 5000'; const parameters: any = {}; // Add parameters for bind variables if (query.deliveryDateIni) { parameters.deliveryDateIni = query.deliveryDateIni; } if (query.deliveryDateEnd) { parameters.deliveryDateEnd = query.deliveryDateEnd; } if (query.codfilial) { const filiais = query.codfilial .split(',') .map((f) => f.trim()) .filter((f) => f); if (filiais.length === 1) { parameters.storeId = filiais[0]; } } if (query.customerId) { parameters.customerId = query.customerId; } if (query.orderId) { parameters.orderId = query.orderId; } if (query.markId) { parameters.markId = query.markId; } if (query.markName) { parameters.markName = query.markName; } const orders = await queryRunner.manager.query(sql, parameters); return orders; } finally { await queryRunner.release(); } } async findInvoice(chavenfe: string): Promise { const queryRunner = this.oracleDataSource.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 JOIN pcclient ON pcnfsaid.codcli = pcclient.codcli JOIN pcusuari ON pcnfsaid.codusur = pcusuari.codusur WHERE pcnfsaid.chavenfe = '${chavenfe}' `; const invoice = await queryRunner.manager.query(sql); if (!invoice || invoice.length === 0) { throw new HttpException( 'Nota fiscal não foi localizada no 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 JOIN pcprodut ON pcmov.codprod = pcprodut.codprod WHERE pcmov.numtransvenda = ${invoice[0].transactionId} `; const itens = await queryRunner.manager.query(sqlItem); invoice[0].itens = itens; return invoice[0]; } finally { await queryRunner.release(); } } async getItens(orderId: string): Promise { const queryRunner = this.oracleDataSource.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(); } } async getCutItens(orderId: string): Promise { const queryRunner = this.oracleDataSource.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 JOIN PCPRODUT ON PCCORTEI.CODPROD = PCPRODUT.CODPROD WHERE PCCORTEI.NUMPED = ${orderId} `; const itens = await queryRunner.manager.query(sql); return itens; } finally { await queryRunner.release(); } } async getOrderDelivery(orderId: string): Promise { const queryRunner = this.oracleDataSource.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 result = await queryRunner.manager.query(sql); return result.length > 0 ? result[0] : null; } finally { await queryRunner.release(); } } async getTransfer(orderId: number): Promise { const queryRunner = this.oracleDataSource.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 LEFT JOIN PCTABDEV ON L.CODMOTIVO = PCTABDEV.coddevol LEFT JOIN PCEMPR ON L.CODFUNCTRANSF = PCEMPR.MATRICULA WHERE L.NUMTRANSVENDA IN ( SELECT NUMTRANSVENDA FROM PCPEDC WHERE PCPEDC.NUMPED = ${orderId} ) `; const result = await queryRunner.manager.query(sql); return result.length > 0 ? result : null; } finally { await queryRunner.release(); } } async getStatusOrder(orderId: number): Promise { const queryRunner = this.oracleDataSource.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 result = await queryRunner.manager.query(sql); return result.length > 0 ? result : null; } finally { await queryRunner.release(); } } async createInvoiceCheck( invoice: InvoiceCheckDto, ): Promise<{ message: string }> { const queryRunner = this.oracleDataSource.createQueryRunner(); await queryRunner.connect(); await queryRunner.startTransaction(); try { const sequenceSql = 'SELECT ESSCONFERENCIANF.NEXTVAL as "id" FROM DUAL'; const result = await queryRunner.manager.query(sequenceSql); const checkId = result[0].id; const sqlMain = ` 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(sqlMain); 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 (error) { await queryRunner.rollbackTransaction(); throw new HttpException(error.message, HttpStatus.BAD_REQUEST); } finally { await queryRunner.release(); } } async getOrderDeliveries(orderId: string) { const queryRunnerOracle = this.oracleDataSource.createQueryRunner(); const queryRunnerPostgres = this.postgresDataSource.createQueryRunner(); await queryRunnerOracle.connect(); await queryRunnerPostgres.connect(); try { const sqlOracle = `SELECT PCPEDC.CODFILIAL as "storeId" ,PCPEDC.DATA as "createDate" ,PCPEDC.NUMPED as "orderId" ,PCPEDC.NUMPEDENTFUT as "orderIdSale" ,PCPEDC.DTENTREGA as "deliveryDate" ,PCPEDC.CODCLI as "customerId" ,PCCLIENT.CLIENTE as "customer" ,( SELECT PCPEDI.TIPOENTREGA FROM PCPEDI WHERE PCPEDI.NUMPED = PCPEDC.NUMPED AND ROWNUM = 1 ) as "deliveryType" ,PCPEDC.NUMITENS as "quantityItens" ,CASE WHEN PCNFSAID.DTCANHOTO IS NOT NULL THEN 'ENTREGA CONFIRMADA' WHEN PCPEDC.POSICAO = 'F' THEN 'FATURADO' WHEN PCPEDC.DTFINALSEP IS NOT NULL THEN 'SEPARADO' WHEN PCPEDC.POSICAO = 'M' THEN 'MONTADO' WHEN PCPEDC.POSICAO = 'L' THEN 'AGUARDANDO SEPARAÇÃO' WHEN PCPEDC.POSICAO = 'P' THEN 'PENDENTE ESTOQUE' WHEN PCPEDC.POSICAO = 'B' THEN 'BLOQUEIO FINANCEIRO' ELSE 'Não Definido' END as "status" ,PCPEDC.TOTPESO as "weight" ,PCPEDC.NUMCAR as "shipmentId" ,CASE WHEN PCPEDC.NUMCAR = 0 THEN NULL ELSE PCCARREG.CODMOTORISTA END as "driverId" ,CASE WHEN PCPEDC.NUMCAR = 0 THEN NULL ELSE PCEMPR.NOME END as "driverName" ,CASE WHEN PCPEDC.NUMCAR = 0 THEN NULL ELSE PCVEICUL.PLACA END as "carPlate" ,CASE WHEN PCPEDC.NUMCAR = 0 THEN NULL ELSE PCVEICUL.OBS2 END as "carIdentification" ,PCPEDC.OBS as "observation" ,PCNFSAID.DTCANHOTO as "deliveryConfirmationDate" FROM PCPEDC, PCCLIENT, PCCARREG, PCVEICUL, PCEMPR, PCNFSAID WHERE PCPEDC.NUMCAR = PCCARREG.NUMCAR AND PCPEDC.NUMTRANSVENDA = PCNFSAID.NUMTRANSVENDA (+) AND PCPEDC.CODCLI = PCCLIENT.CODCLI AND PCCARREG.CODVEICULO = PCVEICUL.CODVEICULO (+) AND PCCARREG.CODMOTORISTA = PCEMPR.MATRICULA (+) AND ( PCPEDC.NUMPEDENTFUT = ${orderId} OR PCPEDC.NUMPEDORIGEM = ${orderId} )`; const orders = await queryRunnerOracle.manager.query(sqlOracle); // Consulta no WMS (Postgres) - Modificada para buscar pelo número do pedido const sqlWMS = ` SELECT p.numero, p.posicao, CASE WHEN p.posicao = 'F' THEN 'FATURADO' WHEN p.posicao = 'C' THEN 'CONCLUIDO' WHEN p.posicao = 'L' THEN 'LIBERADO' WHEN EXISTS ( SELECT 1 FROM movimentacao m2 WHERE m2.numero_pedido = p.numero AND m2.data_inicio_separacao IS NULL ) AND p.posicao = 'M' THEN 'MONTADO' WHEN EXISTS ( SELECT 1 FROM movimentacao m2 WHERE m2.numero_pedido = p.numero AND m2.data_inicio_separacao IS NOT NULL AND m2.data_fim_separacao IS NULL ) AND p.posicao = 'M' THEN 'EM SEPARACAO' WHEN EXISTS ( SELECT 1 FROM movimentacao m2 WHERE m2.numero_pedido = p.numero AND m2.data_fim_separacao IS NOT NULL AND m2.data_inicio_conferencia IS NULL ) AND p.posicao = 'M' THEN 'SEPARACAO FINALIZADA' WHEN EXISTS ( SELECT 1 FROM movimentacao m2 WHERE m2.numero_pedido = p.numero AND m2.data_inicio_conferencia IS NOT NULL AND m2.data_fim_conferencia IS NULL ) AND p.posicao = 'M' THEN 'EM CONFERENCIA' WHEN EXISTS ( SELECT 1 FROM movimentacao m2 WHERE m2.numero_pedido = p.numero AND m2.data_fim_conferencia IS NOT NULL AND (SELECT COUNT(1) FROM volume v WHERE v.numero_pedido = m2.numero_pedido AND v.data_embarque IS NULL) = 0 ) AND p.posicao = 'M' THEN 'CONFERENCIA FINALIZADA' WHEN EXISTS ( SELECT 1 FROM movimentacao m2 WHERE m2.numero_pedido = p.numero AND m2.data_fim_conferencia IS NOT NULL AND (SELECT COUNT(1) FROM volume v WHERE v.numero_pedido = m2.numero_pedido AND v.data_embarque IS NULL) > 0 ) AND p.posicao = 'M' THEN 'EMBARCADO' END as "situacaoPedido" FROM pedido p WHERE p.numero IN ( SELECT DISTINCT m.numero_pedido FROM movimentacao m WHERE m.numero_pedido = $1::bigint OR m.numero_pedido IN ( SELECT CAST(o.orderId AS bigint) FROM UNNEST($2::text[]) o(orderId) WHERE o.orderId ~ '^[0-9]+$' ) ) `; // Criar array com os IDs de pedidos obtidos do Oracle const orderIds = orders.map((o) => o.orderId?.toString() || ''); // Converter orderId para número para evitar erro de tipo const numericOrderId = parseInt(orderId, 10); const ordersWMS = await queryRunnerPostgres.manager.query(sqlWMS, [ numericOrderId, orderIds, ]); // Atualizar status baseado no WMS for (const order of orders) { const orderWMS = ordersWMS.find( (o) => Number(o.numero) === Number(order.orderId), ); if (orderWMS && !order.deliveryConfirmationDate) { order.status = orderWMS.situacaoPedido; } } return orders; } catch (_error) { throw new HttpException( 'Erro ao buscar pedidos', HttpStatus.INTERNAL_SERVER_ERROR, ); } finally { await queryRunnerOracle.release(); await queryRunnerPostgres.release(); } } async getLeadtimeWMS(orderId: string): Promise { const queryRunnerPostgres = this.postgresDataSource.createQueryRunner(); const queryRunnerOracle = this.oracleDataSource.createQueryRunner(); await queryRunnerPostgres.connect(); await queryRunnerOracle.connect(); try { // Consulta no Oracle const sqlOracle = ` SELECT D.ETAPA as "etapa", D.DESCRICAO_ETAPA as "descricaoEtapa", D.DATA as "data", D.CODIGOFUNCIONARIO as "codigoFuncionario", D.NOMEFUNCIONARIO as "nomeFuncionario", D.NUMEROPEDIDO as "numeroPedido" FROM ESVACOMPANHAMENTOPEDIDO D WHERE D.NUMEROPEDIDO = ${orderId} ORDER BY D.ETAPA `; const dataOracle = await queryRunnerOracle.manager.query(sqlOracle); // Consulta no Postgres const sqlPostgres = ` SELECT DADOS.ETAPA as "etapa", DADOS.DESCRICAO_ETAPA as "descricaoEtapa", DADOS.DATA as "data", DADOS.CODIGO_FUNCIONARIO as "codigoFuncionario", DADOS.NOME_FUNCIONARIO as "nomeFuncionario", DADOS.NUMERO_PEDIDO as "numeroPedido" FROM ( SELECT 3 AS ETAPA, 'Inicio Separação' AS DESCRICAO_ETAPA, MIN(m.data_inicio_separacao) AS DATA, MAX(m.codigo_separador) AS CODIGO_FUNCIONARIO, (SELECT u.nome FROM usuario u WHERE u.id = MAX(m.codigo_separador)) AS NOME_FUNCIONARIO, m.numero_pedido FROM movimentacao m WHERE m.data_inicio_separacao >= '2025-01-01' AND m.numero_pedido > 0 AND m.data_inicio_separacao IS NOT NULL GROUP BY m.numero_pedido UNION ALL SELECT 4, 'Separado', MIN(m.data_fim_separacao), MAX(m.codigo_separador), (SELECT u.nome FROM usuario u WHERE u.id = MAX(m.codigo_separador)), m.numero_pedido FROM movimentacao m WHERE m.data_inicio_separacao >= '2025-01-01' AND m.numero_pedido > 0 AND m.data_fim_separacao IS NOT NULL GROUP BY m.numero_pedido UNION ALL SELECT 5, 'Inicio Conferência', MIN(m.data_inicio_conferencia), MAX(m.codigo_conferente), (SELECT u.nome FROM usuario u WHERE u.id = MAX(m.codigo_conferente)), m.numero_pedido FROM movimentacao m WHERE m.data_inicio_conferencia IS NOT NULL AND m.numero_pedido > 0 GROUP BY m.numero_pedido UNION ALL SELECT 6, 'Fim Conferência', MIN(m.data_fim_conferencia), MAX(m.codigo_conferente), (SELECT u.nome FROM usuario u WHERE u.id = MAX(m.codigo_conferente)), m.numero_pedido FROM movimentacao m WHERE m.data_fim_conferencia IS NOT NULL AND m.numero_pedido > 0 GROUP BY m.numero_pedido UNION ALL SELECT 7, 'Embarcado', MAX(v.data_embarque), v.usuario_embarque_id, (SELECT u.nome FROM usuario u WHERE u.id = v.usuario_embarque_id), m.numero_pedido FROM movimentacao m JOIN volume v ON m.numero_pedido = v.numero_pedido WHERE v.data_embarque IS NOT NULL AND m.numero_pedido > 0 GROUP BY v.usuario_embarque_id, m.numero_pedido ) DADOS WHERE DADOS.numero_pedido = $1 ORDER BY DADOS.numero_pedido, DADOS.ETAPA; `; const dataPostgres = await queryRunnerPostgres.manager.query( sqlPostgres, [orderId], ); // Junta os dados Oracle + Postgres const leadtime = [...dataOracle, ...dataPostgres]; // Ordena pela etapa (opcional, para garantir ordem) return leadtime.sort((a, b) => a.etapa - b.etapa); } catch (_error) { throw new HttpException( 'Erro ao buscar dados de leadtime do WMS', HttpStatus.INTERNAL_SERVER_ERROR, ); } finally { await queryRunnerPostgres.release(); await queryRunnerOracle.release(); } } /** * Busca as transportadoras de um pedido específico */ async getOrderCarriers(orderId: number): Promise { const sql = ` SELECT DISTINCT PCPEDC.CODFORNECFRETE as "carrierId", PCFORNEC.FORNECEDOR as "carrierName", PCPEDC.CODFORNECFRETE || ' - ' || PCFORNEC.FORNECEDOR as "carrierDescription" FROM PCPEDC LEFT JOIN PCFORNEC ON PCPEDC.CODFORNECFRETE = PCFORNEC.CODFORNEC WHERE PCPEDC.NUMPED = :0 AND PCPEDC.CODFORNECFRETE IS NOT NULL AND PCPEDC.CODFORNECFRETE > 0 ORDER BY PCPEDC.CODFORNECFRETE `; return await this.oracleDataSource.query(sql, [orderId]); } /** * Busca todas as marcas disponíveis */ async getAllMarks(): Promise { const sql = ` SELECT p.MARCA, p.CODMARCA, p.ATIVO FROM PCMARCA p WHERE p.ATIVO = 'S' ORDER BY p.MARCA `; return await this.oracleDataSource.query(sql); } /** * Busca marcas por nome (busca parcial) */ async getMarksByName(markName: string): Promise { const sql = ` SELECT p.MARCA, p.CODMARCA, p.ATIVO FROM PCMARCA p WHERE p.ATIVO = 'S' AND UPPER(p.MARCA) LIKE UPPER('%' || :markName || '%') ORDER BY p.MARCA `; return await this.oracleDataSource.query(sql, [markName]); } /** * Busca o NUMTRANSVENDA de um pedido específico * @param orderId - ID do pedido * @returns NUMTRANSVENDA do pedido ou null se não encontrado */ async getOrderTransactionId(orderId: string): Promise { const sql = ` SELECT NUMTRANSVENDA FROM PCPEDC WHERE NUMPED = :1 `; const result = await this.oracleDataSource.query(sql, [orderId]); return result.length > 0 ? result[0].NUMTRANSVENDA : null; } /** * Busca entregas realizadas por transactionId * @param query - Filtros para a consulta de entregas realizadas incluindo transactionId * @returns Lista de entregas realizadas */ async getCompletedDeliveriesByTransactionId(query: { transactionId: number; limit: number; offset: number; }): Promise { const sql = ` SELECT ESTENTREGAS.CODSAIDA AS "outId" ,ESTENTREGAS.NUMTRANSVENDA AS "transactionId" ,ESTENTREGAS.DATA AS "deliveryDate" ,PCNFSAID.NUMNOTA AS "invoiceNumber" ,PCNFSAID.CODCLI AS "customerId" ,PCCLIENT.CLIENTE AS "customerName" ,ESTENTREGAS.DOCUMENTORECEBEDOR AS "deliveryDoc" ,ESTENTREGAS.NOMERECEBEDOR AS "deliveryName" ,ESTENTREGAS.LAT AS "lat" ,ESTENTREGAS.LNG AS "lng" ,ESTENTREGAS.AVARIA AS "existBreakdown" ,ESTENTREGAS.DEVOLUCAO AS "existReturn" ,ESTENTREGAS.MOTIVODEVOLUCAO AS "obsReturn" ,PCNFSAID.DTCANHOTO AS "dataCanhoto" ,PCNFSAID.NUMTRANSVENDA AS "transactionIdInvoice" ,PCNFSAID.CODFUNCCANHOTO AS "invoiceUserId" ,PCEMPR.NOME AS "invoiceUserName" ,ESTSITUACAOENTREGA.SITUACAO AS "deliveryStatus" ,PCCARREG.CODMOTORISTA AS "driverId" ,MOTORISTA.NOME AS "driverName" FROM ESTENTREGAS, PCNFSAID, PCCLIENT, PCEMPR, ESTSITUACAOENTREGA, ESTSAIDAVEICULOCARREG, PCCARREG, PCEMPR MOTORISTA WHERE ESTENTREGAS.NUMTRANSVENDA = PCNFSAID.NUMTRANSVENDA AND ESTENTREGAS.CODSAIDA = ESTSAIDAVEICULOCARREG.CODSAIDA AND PCNFSAID.NUMCAR = ESTSAIDAVEICULOCARREG.NUMCAR AND PCNFSAID.NUMCAR = PCCARREG.NUMCAR AND PCCARREG.CODMOTORISTA = MOTORISTA.MATRICULA (+) AND PCNFSAID.CODCLI = PCCLIENT.CODCLI AND PCNFSAID.CODFUNCCANHOTO = PCEMPR.MATRICULA (+) AND ESTENTREGAS.CODSAIDA = ESTSITUACAOENTREGA.CODSAIDA (+) AND PCNFSAID.CODCLI = ESTSITUACAOENTREGA.CODCLI (+) AND ESTENTREGAS.NUMTRANSVENDA = :1 ORDER BY ESTENTREGAS.DATA DESC OFFSET :2 ROWS FETCH NEXT :3 ROWS ONLY `; const deliveries = await this.oracleDataSource.query(sql, [ query.transactionId, query.offset, query.limit, ]); // Buscar imagens para cada entrega for (let index = 0; index < deliveries.length; index++) { const delivery = deliveries[index]; const sqlImages = ` SELECT URL FROM ESTENTREGASIMAGENS WHERE CODSAIDA = :1 AND NUMTRANSVENDA = :2 `; const images = await this.oracleDataSource.query(sqlImages, [ delivery.outId, delivery.transactionId, ]); delivery.urlImages = images.map((image: any) => image.URL); } // Converter os resultados para o formato esperado return deliveries.map((row: any) => ({ outId: row.outId, transactionId: row.transactionId, deliveryDate: row.deliveryDate, invoiceNumber: row.invoiceNumber, customerId: row.customerId, customerName: row.customerName, deliveryDoc: row.deliveryDoc, deliveryName: row.deliveryName, lat: row.lat, lng: row.lng, existBreakdown: row.existBreakdown, existReturn: row.existReturn, obsReturn: row.obsReturn, dataCanhoto: row.dataCanhoto, transactionIdInvoice: row.transactionIdInvoice, invoiceUserId: row.invoiceUserId, invoiceUserName: row.invoiceUserName, deliveryStatus: row.deliveryStatus, driverId: row.driverId, driverName: row.driverName, urlImages: [...row.urlImages], })); } /** * Busca entregas realizadas com filtros opcionais * @param query - Filtros para a consulta de entregas realizadas * @returns Lista de entregas realizadas */ async getCompletedDeliveries( query: DeliveryCompletedQuery, ): Promise { let sql = ` SELECT ESTENTREGAS.CODSAIDA AS "outId" ,ESTENTREGAS.NUMTRANSVENDA AS "transactionId" ,ESTENTREGAS.DATA AS "deliveryDate" ,PCNFSAID.NUMNOTA AS "invoiceNumber" ,PCNFSAID.CODCLI AS "customerId" ,PCCLIENT.CLIENTE AS "customerName" ,ESTENTREGAS.DOCUMENTORECEBEDOR AS "deliveryDoc" ,ESTENTREGAS.NOMERECEBEDOR AS "deliveryName" ,ESTENTREGAS.LAT AS "lat" ,ESTENTREGAS.LNG AS "lng" ,ESTENTREGAS.AVARIA AS "existBreakdown" ,ESTENTREGAS.DEVOLUCAO AS "existReturn" ,ESTENTREGAS.MOTIVODEVOLUCAO AS "obsReturn" ,PCNFSAID.DTCANHOTO AS "dataCanhoto" ,PCNFSAID.NUMTRANSVENDA AS "transactionIdInvoice" ,PCNFSAID.CODFUNCCANHOTO AS "invoiceUserId" ,PCEMPR.NOME AS "invoiceUserName" ,ESTSITUACAOENTREGA.SITUACAO AS "deliveryStatus" ,PCCARREG.CODMOTORISTA AS "driverId" ,MOTORISTA.NOME AS "driverName" FROM ESTENTREGAS, PCNFSAID, PCCLIENT, PCEMPR, ESTSITUACAOENTREGA, ESTSAIDAVEICULOCARREG, PCCARREG, PCEMPR MOTORISTA WHERE ESTENTREGAS.NUMTRANSVENDA = PCNFSAID.NUMTRANSVENDA AND ESTENTREGAS.CODSAIDA = ESTSAIDAVEICULOCARREG.CODSAIDA AND PCNFSAID.NUMCAR = ESTSAIDAVEICULOCARREG.NUMCAR AND PCNFSAID.NUMCAR = PCCARREG.NUMCAR AND PCCARREG.CODMOTORISTA = MOTORISTA.MATRICULA (+) AND PCNFSAID.CODCLI = PCCLIENT.CODCLI AND PCNFSAID.CODFUNCCANHOTO = PCEMPR.MATRICULA (+) AND ESTENTREGAS.CODSAIDA = ESTSITUACAOENTREGA.CODSAIDA (+) AND PCNFSAID.CODCLI = ESTSITUACAOENTREGA.CODCLI (+) `; const parameters: any[] = []; let paramIndex = 1; // Filtros opcionais if (query.startDate) { sql += ` AND TRUNC(ESTENTREGAS.DATA) >= TO_DATE(:${paramIndex},'YYYY-MM-DD')`; parameters.push(query.startDate); paramIndex++; } if (query.endDate) { sql += ` AND TRUNC(ESTENTREGAS.DATA) <= TO_DATE(:${paramIndex},'YYYY-MM-DD')`; parameters.push(query.endDate); paramIndex++; } if (query.outId) { sql += ` AND ESTENTREGAS.CODSAIDA = :${paramIndex}`; parameters.push(query.outId); paramIndex++; } if (query.driverName) { sql += ` AND UPPER(MOTORISTA.NOME) LIKE UPPER(:${paramIndex})`; parameters.push(`%${query.driverName}%`); paramIndex++; } if (query.customerId && query.customerId > 0) { sql += ` AND PCCLIENT.CODCLI = :${paramIndex}`; parameters.push(query.customerId); paramIndex++; } if (query.customerName) { sql += ` AND UPPER(PCCLIENT.CLIENTE) LIKE UPPER(:${paramIndex})`; parameters.push(`%${query.customerName}%`); paramIndex++; } if (query.orderNumber) { sql += ` AND PCNFSAID.NUMNOTA = :${paramIndex}`; parameters.push(query.orderNumber); paramIndex++; } if (query.status) { sql += ` AND ESTSITUACAOENTREGA.SITUACAO = :${paramIndex}`; parameters.push(query.status); paramIndex++; } // Ordenação sql += ` ORDER BY ESTENTREGAS.DATA DESC`; // Paginação const limit = query.limit || 100; const offset = query.offset || 0; sql += ` OFFSET :${paramIndex} ROWS FETCH NEXT :${ paramIndex + 1 } ROWS ONLY`; parameters.push(offset); parameters.push(limit); const deliveries = await this.oracleDataSource.query(sql, parameters); // Buscar imagens para cada entrega for (let index = 0; index < deliveries.length; index++) { const delivery = deliveries[index]; const sqlImages = ` SELECT URL FROM ESTENTREGASIMAGENS WHERE CODSAIDA = :1 AND NUMTRANSVENDA = :2 `; const images = await this.oracleDataSource.query(sqlImages, [ delivery.outId, delivery.transactionId, ]); delivery.urlImages = images.map((image: any) => image.URL); } // Converter os resultados para o formato esperado return deliveries.map((row: any) => ({ outId: row.outId, transactionId: row.transactionId, deliveryDate: row.deliveryDate, invoiceNumber: row.invoiceNumber, customerId: row.customerId, customerName: row.customerName, deliveryDoc: row.deliveryDoc, deliveryName: row.deliveryName, lat: row.lat, lng: row.lng, existBreakdown: row.existBreakdown, existReturn: row.existReturn, obsReturn: row.obsReturn, dataCanhoto: row.dataCanhoto, transactionIdInvoice: row.transactionIdInvoice, invoiceUserId: row.invoiceUserId, invoiceUserName: row.invoiceUserName, deliveryStatus: row.deliveryStatus, driverId: row.driverId, driverName: row.driverName, urlImages: [...row.urlImages], })); } }