update conf set confrelease = '13409'; ------------------------------------------------------------------------------------------------ -- DROP FUNCTION public.f_processar_fv(int4, int4); CREATE OR REPLACE FUNCTION public.f_processar_fv(integer, integer) RETURNS TABLE(frprocpvcod integer, frpropedcod integer, frpropednum integer, frpromens text) LANGUAGE plpgsql AS $function$ DECLARE /* 23/11/22 - David: Criação da função f_processar_fv 11/02/26 - Atualização: Adição de campos de geolocalização 17/03/26 - Atualização: Validações de cabeçalho e itens (bloqueio, horário, cliente, boleto/opnf, estoque, desconto, limite de crédito, corte, promoção, desconto por quantidade, formatação de valores, duplicidade, RCA, produto ativo/fora de linha, data programada, divergência de valor total, itens duplicados) 26/03/26 - Alteração do campo ped_referenciaerp para v_pvcod 06/04/26 - Correção: comparações de preço passaram a usar ROUND(...,2) para evitar cortes por imprecisão numérica interna 13/04/26 - Adicionar o pvcod no retorno 21/05/26 - Validação 8-B: inadimplência portada do Delphi — parcelas em atraso (confdiasatraso) e cheque devolvido definem status AP em vez de AA, sem recusar o pedido. 21/05/26 - Correção: pvbloq inicializado com 'N' para garantir preenchimento obrigatório em todos os pedidos FV. Campo era NULL para pedidos aprovados sem bloqueio, impedindo listagem na rotina Faturar Pedido (Thunder). 21/05/26 - Validação 11: valor mínimo para boleto por cliente ficar abaixo de cli_valorminbol ou quando valor atendido não cobrir as despesas de boleto (clidespbol * parcelas). 28/05/26 - Corrigir cálculo preço min e max para usar os campos da f_preco 09/06/26 - Tratar a troca para ser enviada como pendente - Tratar retorno de debito e credito para o vendedor - Adicionar o campo de resposta no update da PV, estava alimentando o campo antigo. 10/06/26 - Correção Validação 9-B: recRef protegido contra NULL/não-numérico (NULLIF+TRIM) Validação 12: removida duplicidade de impressão do Deb/Cred Vendedor 11/06/26 - Correção UPDATE pv: pvvldesc calculado a partir dos itens gravados na PVI (pvivltab * pviqtdeate vs pvivlven * pviqtdeate), pois o valor tabela só está disponível após a inserção dos itens. Positivo = desconto; Negativo = aumento. Validação 9-B movida para após loop de itens (v_soma_pedido_ate disponível) Validação 12: removida duplicidade de impressão do Deb/Cred Vendedor 22/06/26 - Correção Validação 12: v_debcred_pedido recusava quando negativo (crédito); corrigido para recusar somente quando positivo (débito) e saldo insuficiente. Correção Validação 9-B: bloco estava posicionado antes do loop de itens, fazendo v_soma_pedido_ate = 0.00 na impressão. Movido para após o totalizador. Adicionadas informações da troca na mensagem de retorno mesmo quando aprovada. 23/06/26 - Validação 1: pré-verificação de ped_importado = 2 antes do FOR loop: retorna ped_obsretorno já gravado sem reprocessar. Validação 1: dentro do loop, se não encontrado na PV, limpa pedi órfão de tentativas anteriores interrompidas antes de reprocessar. 23/06/26 - Validação 12: corrigido cálculo do deb/cred. Consulta de saldo passa a usar rca_d_debcred como data inicial (era NULL). Busca dc_limite junto com dc_saldo em um único SELECT da f_calc_debcred. Condição de recusa corrigida: bloqueia quando (limite + saldo + debcred_pedido) < 0, cobrindo crédito negativo que ultrapassa o limite (cenário anterior não detectava). 15/07/26 - correção da verificação 1 tratar v_sta */ p_pedcod ALIAS FOR $1; p_empresa ALIAS FOR $2; rec_ped RECORD; rec_item RECORD; v_pvcod INTEGER; v_agora DATE; v_valido BOOLEAN; v_resposta TEXT; v_bloq TEXT; v_bloqusuparcod INTEGER; v_bloqhorario DATE; v_bloqobs TEXT; v_qtdedisp NUMERIC(14,4); v_qtdeate NUMERIC(14,4); v_qtdeatecar NUMERIC(14,4); v_vltab NUMERIC(14,4); v_vlven NUMERIC(14,4); v_custocompra NUMERIC(14,4); v_custoreal NUMERIC(14,4); v_basedebcred NUMERIC(14,4); v_calcDebCred TEXT; v_vltab_embcod INTEGER; v_sta TEXT; v_sit TEXT; -- Configurações da empresa v_conf_sempre_bloqueado TEXT; v_conf_sempre_pendente TEXT; v_conf_recusa_lim_cred TEXT; v_conf_recusa_item_sem_est TEXT; v_conf_vende_bo_n_contab TEXT; v_conf_pv_clibloq TEXT; v_conf_perc_min NUMERIC(14,4); v_conf_perc_max NUMERIC(14,4); v_conf_corte TEXT; v_conf_hora_ini VARCHAR(10); v_conf_hora_fim VARCHAR(10); -- Controle de corte/itens v_item_aceito BOOLEAN; v_tratou_corte BOOLEAN; v_item_ate INTEGER; v_soma_pedido NUMERIC(14,4); v_soma_pedido_ate NUMERIC(14,4); v_perc_dif NUMERIC(14,4); -- Desconto por quantidade v_dq_vlven NUMERIC(14,4); v_dq_qtde INTEGER; v_dq_qtate INTEGER; v_dq_taxa NUMERIC(14,4); v_dq_vl NUMERIC(14,4); -- Dados do cliente/operação v_clibloq TEXT; v_clilimdisp NUMERIC(14,4); v_opnfsta TEXT; v_tctdoc TEXT; v_cli_valorminbol NUMERIC(14,4); v_clidespbol NUMERIC(14,4); v_qtdeparcelas INTEGER; v_valor_parcela NUMERIC(14,4); v_valor_despesas NUMERIC(14,4); -- Duplicidade v_pvcod_existente INTEGER; v_ped_dup_clicod INTEGER; v_ped_dup_rcacod INTEGER; v_ped_dup_vltotal NUMERIC(14,4); -- RCA v_parsit TEXT; v_rcaav TEXT; -- Produto v_estdispfv TEXT; v_estforalinha TEXT; -- Promoção v_promsta TEXT; v_promdtini DATE; v_promdtfim DATE; -- Divergência de valor v_soma_itens NUMERIC(14,4); -- Inadimplência v_possui_atraso BOOLEAN; v_cheque_devolvido BOOLEAN; v_dias_atraso INTEGER; v_mens_inad TEXT; v_fprpercdesctab NUMERIC(14,4); v_fprpercaumtab NUMERIC(14,4); vminpermitido NUMERIC(14,2); vmaxpermitido NUMERIC(14,2); v_eh_troca BOOLEAN; v_fdebcred NUMERIC(14,4); v_soma_basedebcred NUMERIC(14,4); v_soma_vltab NUMERIC(14,4); v_cli_perc_bon_troca NUMERIC(14,4); v_ped_ref_vltotalatecar NUMERIC(14,4); v_pvreftotal NUMERIC(14,4); v_pedrefcod INTEGER; v_valor_limite_troca NUMERIC(14,4); v_dc_limite NUMERIC(14,4); v_dc_dini DATE; BEGIN SELECT now()::date INTO v_agora; -- ============================================================ -- PRÉ-VERIFICAÇÃO: pedido já foi processado com sucesso? -- Se ped_importado = 2, retorna o retorno salvo sem reprocessar. -- ============================================================ DECLARE v_pre_importado INTEGER; v_pre_obsretorno TEXT; v_pre_pvcodref INTEGER; BEGIN SELECT ped_importado, ped_obsretorno, COALESCE(NULLIF(TRIM(ped_referenciaerp), '')::integer, 0) INTO v_pre_importado, v_pre_obsretorno, v_pre_pvcodref FROM ipedi.ped WHERE ped_codigo = p_pedcod AND ped_filcod = p_empresa; IF v_pre_importado = 2 THEN RETURN QUERY SELECT p_pedcod, v_pre_pvcodref::integer, v_pre_pvcodref::integer, v_pre_obsretorno::text; RETURN; END IF; END; FOR rec_ped IN SELECT ped_codigo, ped_referenciaerp, ped_rcacod AS pvcadusuparcod, ped_dtlan AS pvcadhorario, 'IMPORTADO PELO THUNDERAPI' AS pvacao, ped_filcod AS pvempparcod, 'FV' AS pvcanal, 'AA' AS pvsta, ped_clicod AS pvcliparcod, pardes, ped_tvcod AS pvopnfcod, ped_plpgcod AS pvplpgcod, ped_cobcod AS pvtccod, ped_vltotal AS pvvltotal, ped_vltotal AS pvvltotalate, ped_vltotal AS pvvltotalatecar, ped_indice AS pvindice, ped_rcacod AS pvrcaparcod, ped_obs AS pvobsped, ped_obsnota AS pvobsnf, ped_numped as pvfvcodrem, ped_numpedcli AS pvpedcli, ped_dtprog AS pvdtprog, ped_latitude AS pvlatitude, ped_longitude AS pvlongitude, ped_accuracy AS pvaccuracy, ped_timestamp_geo AS pvtimestamp_geo, (SELECT lpcod FROM lp WHERE lpcod = (SELECT f_livro_do_cliente FROM f_livro_do_cliente(ped_clicod, ped_filcod))) AS lpcod, (SELECT lpdes FROM lp WHERE lpcod = (SELECT f_livro_do_cliente FROM f_livro_do_cliente(ped_clicod, ped_filcod))) AS lpdes, 'ENVIADO' || chr(10) || 'Dt.Lancamento.....: ' || to_char(ped_dtlan, 'DD/MM/YYYY') || chr(10) || 'Dt.Processamento..: ' || to_char(now(), 'DD/MM/YYYY HH24:MI:SS') || chr(10) || '** Pedido enviado com sucesso' || chr(10) || 'Cod.Cliente.......: ' || ped_clicod || chr(10) || 'Cliente...........: ' || pardes || chr(10) || 'Livro.............: ' || (SELECT lpcod FROM lp WHERE lpcod = (SELECT f_livro_do_cliente FROM f_livro_do_cliente(ped_clicod, ped_filcod))) || ' - ' || (SELECT lpdes FROM lp WHERE lpcod = (SELECT f_livro_do_cliente FROM f_livro_do_cliente(ped_clicod, ped_filcod))) || chr(10) || 'Pedido no Palm....: ' || ped_codigo || chr(10) || 'Valor Pedido......: ' || TO_CHAR(ped_vltotal, 'FM999999990.00') AS pedresposta FROM ipedi.ped JOIN par ON ped_clicod = parcod WHERE ped_importado = 1 AND ped_codigo = p_pedcod AND ped_filcod = p_empresa LOOP -- Carregar configurações SELECT conf_fv_sempre_bloqueado, conf_fv_sempre_pendente, conf_fv_recusa_lim_cred, conf_fv_recusa_item_sem_est, conf_fv_vende_bo_opnf_n_contab, conf_fv_pv_clibloq, COALESCE(conf_fv_perc_min, 0), COALESCE(conf_fv_perc_max, 0), confcondicaocortepvfv, confhorarioinireceberfv, confhorariofimreceberfv INTO v_conf_sempre_bloqueado, v_conf_sempre_pendente, v_conf_recusa_lim_cred, v_conf_recusa_item_sem_est, v_conf_vende_bo_n_contab, v_conf_pv_clibloq, v_conf_perc_min, v_conf_perc_max, v_conf_corte, v_conf_hora_ini, v_conf_hora_fim FROM conf WHERE confempparcod = rec_ped.pvempparcod; -- Inicializar controles v_valido := TRUE; v_sta := 'AA'; v_sit := 'APROVADO'; v_bloq := 'N'; v_bloqusuparcod := NULL; v_bloqhorario := NULL; v_bloqobs := NULL; v_tratou_corte := FALSE; v_item_ate := 0; v_soma_pedido := 0; v_soma_pedido_ate := 0; v_soma_itens := 0; v_pvcod := 0; v_resposta := rec_ped.pedresposta; v_clibloq := NULL; v_clilimdisp := 0; v_opnfsta := NULL; v_tctdoc := NULL; v_cli_valorminbol := 0; v_clidespbol := 0; v_qtdeparcelas := 1; v_valor_parcela := 0; v_valor_despesas := 0; v_fdebcred := 0; v_dc_limite := 0; v_soma_basedebcred := 0; v_soma_vltab := 0; v_eh_troca := FALSE; -- ============================================================ -- VALIDAÇÃO 1: DUPLICIDADE -- Chave correta da origem: ped_rcacod + ped_codigo -- ============================================================ SELECT pvcod, pvcliparcod, pvrcaparcod, pvvltotal INTO v_pvcod_existente, v_ped_dup_clicod, v_ped_dup_rcacod, v_ped_dup_vltotal FROM pv WHERE pvrefpvcod = rec_ped.ped_codigo AND pvrcaparcod = rec_ped.pvcadusuparcod LIMIT 1; IF FOUND THEN -- Mesmo pedido de origem do mesmo RCA já processado anteriormente IF v_ped_dup_rcacod = rec_ped.pvcadusuparcod THEN v_resposta := rec_ped.pedresposta || chr(10) || '** PEDIDO JA PROCESSADO ANTERIORMENTE **' || chr(10) || 'Pedido ERP existente: ' || v_pvcod_existente || chr(10) || 'Referencia FV: ' || rec_ped.pvfvcodrem || chr(10) || 'Pedido origem: ' || rec_ped.ped_codigo || chr(10) || 'RCA origem: ' || rec_ped.pvcadusuparcod; UPDATE ipedi.ped SET ped_importado = 2, ped_obsretorno = v_resposta WHERE ped_codigo = p_pedcod AND ped_filcod = p_empresa; RETURN QUERY SELECT p_pedcod, v_pvcod_existente::integer, v_pvcod_existente::integer, v_resposta::text; RETURN; ELSE v_valido := FALSE; v_resposta := v_resposta || chr(10) || '** PEDIDO RECUSADO **' || chr(10) || 'Motivo: Pedido ja vinculado a outro RCA' || chr(10) || 'Pedido origem: ' || rec_ped.ped_codigo || chr(10) || 'RCA enviado: ' || rec_ped.pvcadusuparcod || chr(10) || 'RCA encontrado: ' || v_ped_dup_rcacod; END IF; END IF; -- ============================================================ -- VALIDAÇÃO 2: RCA ATIVO E USA FV -- ============================================================ IF v_valido THEN SELECT parsit INTO v_parsit FROM par WHERE parcod = rec_ped.pvcadusuparcod; SELECT rcaav INTO v_rcaav FROM rca WHERE rcaparcod = rec_ped.pvcadusuparcod; IF v_parsit = 'I' THEN v_valido := FALSE; v_resposta := v_resposta || chr(10) || '** PEDIDO RECUSADO **' || chr(10) || 'Motivo: Vendedor inativo (RCA: ' || rec_ped.pvcadusuparcod || ')'; ELSIF v_rcaav = 'N' THEN v_valido := FALSE; v_resposta := v_resposta || chr(10) || '** PEDIDO RECUSADO **' || chr(10) || 'Motivo: Vendedor nao habilitado para o Forca de Vendas (RCA: ' || rec_ped.pvcadusuparcod || ')'; END IF; END IF; -- ============================================================ -- VALIDAÇÃO 3: SEMPRE BLOQUEADO -- ============================================================ IF v_valido AND v_conf_sempre_bloqueado = 'S' THEN v_bloq := 'S'; v_bloqusuparcod := 100; v_bloqhorario := date(now()); v_bloqobs := 'BLOQUEADO PELA CONFIGURACAO PADRAO'; v_sta := 'AP'; v_sit := 'BLOQUEADO'; v_valido := FALSE; v_resposta := v_resposta || chr(10) || '** PEDIDO BLOQUEADO **' || chr(10) || 'Motivo: Bloqueado pela configuracao padrao'; END IF; -- ============================================================ -- VALIDAÇÃO 4: HORÁRIO DE RECEPÇÃO -- ============================================================ IF v_valido AND v_conf_hora_ini IS NOT NULL AND v_conf_hora_fim IS NOT NULL THEN IF now()::time < v_conf_hora_ini::time OR now()::time > v_conf_hora_fim::time THEN v_valido := FALSE; v_resposta := v_resposta || chr(10) || '** PEDIDO RECUSADO **' || chr(10) || 'Motivo: Fora do horario de recepcao de pedidos' || chr(10) || 'Horario permitido: ' || v_conf_hora_ini || ' ate ' || v_conf_hora_fim; END IF; END IF; -- ============================================================ -- VALIDAÇÃO 5: CLIENTE BLOQUEADO -- ============================================================ IF v_valido THEN SELECT clibloq, COALESCE(cli_valorminbol, 0), COALESCE(clidespbol, 0) INTO v_clibloq, v_cli_valorminbol, v_clidespbol FROM cli WHERE cliparcod = rec_ped.pvcliparcod; IF v_clibloq = 'S' THEN IF v_conf_pv_clibloq = 'S' THEN v_sta := 'AA'; v_sit := 'APROVADO'; v_bloq := 'S'; v_bloqusuparcod := rec_ped.pvcadusuparcod; v_bloqhorario := date(now()); v_bloqobs := 'CLIENTE BLOQUEADO'; v_resposta := v_resposta || chr(10) || '** Pedido sujeito a aprovacao, cliente bloqueado.'; ELSE v_valido := FALSE; v_resposta := v_resposta || chr(10) || '** PEDIDO RECUSADO **' || chr(10) || 'Motivo: Cliente BLOQUEADO'; END IF; END IF; END IF; -- ============================================================ -- VALIDAÇÃO 6: OPERAÇÃO NÃO CONTÁBIL COM BOLETO -- ============================================================ IF v_valido THEN SELECT opnfsta INTO v_opnfsta FROM opnf WHERE opnfcod = rec_ped.pvopnfcod; SELECT tctdoc INTO v_tctdoc FROM tc WHERE tccod = rec_ped.pvtccod; IF v_conf_vende_bo_n_contab = 'N' AND v_tctdoc = 'BO' AND v_opnfsta = 'G' THEN v_valido := FALSE; v_resposta := v_resposta || chr(10) || '** PEDIDO RECUSADO **' || chr(10) || 'Motivo: Venda com operacao nao contabil (' || v_opnfsta || ') nao permitida para BOLETO'; END IF; END IF; -- ============================================================ -- VALIDAÇÃO 7: DATA PROGRAMADA NO PASSADO -- ============================================================ IF v_valido AND rec_ped.pvdtprog < date(now()) THEN IF v_sta = 'AA' THEN v_sta := 'AP'; END IF; v_resposta := v_resposta || chr(10) || '** Pedido sujeito a aprovacao: data programada no passado' || chr(10) || 'Data informada: ' || to_char(rec_ped.pvdtprog, 'DD/MM/YYYY') || chr(10) || 'Data atual.....: ' || to_char(now(), 'DD/MM/YYYY'); END IF; -- ============================================================ -- VALIDAÇÃO 8: SEMPRE PENDENTE -- ============================================================ IF v_valido AND v_conf_sempre_pendente = 'S' AND v_sta = 'AA' THEN v_sta := 'AP'; v_resposta := v_resposta || chr(10) || '** Pedido sujeito a aprovacao conforme configuracao padrao.'; END IF; -- ============================================================ -- VALIDAÇÃO 8-B: INADIMPLÊNCIA -- ============================================================ IF v_valido THEN SELECT COALESCE(confdiasatraso, 0) INTO v_dias_atraso FROM conf WHERE confempparcod = rec_ped.pvempparcod; SELECT EXISTS ( SELECT 1 FROM doc JOIN tc ON tccod = doctccod WHERE docsta NOT IN ('BA', 'EX', 'RN') AND docdevparcod = rec_ped.pvcliparcod AND doctipo IN ('CRC', 'CRO') AND COALESCE(tctipo, '') NOT IN ('CARTAO_CREDITO', 'CARTAO_DEBITO', 'DINHEIRO', 'OUTRO') AND COALESCE(docavalistaparcod, 0) = 0 AND (CAST(now() AS date) - docdvenc) >= v_dias_atraso ) INTO v_possui_atraso; SELECT EXISTS ( SELECT 1 FROM doc WHERE docsta = 'DD' AND docdevparcod = rec_ped.pvcliparcod AND doctipo = 'CRC' ) INTO v_cheque_devolvido; IF v_possui_atraso OR v_cheque_devolvido THEN v_mens_inad := ''; IF v_possui_atraso THEN v_mens_inad := 'cliente possui parcela(s) em atraso'; END IF; IF v_cheque_devolvido THEN v_mens_inad := v_mens_inad || CASE WHEN v_mens_inad <> '' THEN ' e ' ELSE '' END || 'cheque devolvido'; END IF; IF v_sta = 'AA' THEN v_sta := 'AP'; END IF; v_resposta := v_resposta || chr(10) || '** Pedido sujeito a aprovacao: ' || v_mens_inad || '.'; END IF; END IF; -- ============================================================ -- VALIDAÇÃO 9: PEDIDO DE TROCA — STATUS PENDENTE OBRIGATÓRIO -- ============================================================ IF v_valido THEN SELECT 1 INTO v_eh_troca FROM opnf WHERE opnfcod = rec_ped.pvopnfcod AND opnftopnfcod = 'TR' LIMIT 1; v_eh_troca := FOUND; IF v_eh_troca AND v_sta = 'AA' THEN v_sta := 'AP'; v_resposta := v_resposta || chr(10) || '** Pedido de troca: gravado com status PENDENTE aguardando aprovacao manual.'; END IF; END IF; -- ============================================================ -- VALIDAÇÃO 10: DIVERGÊNCIA VALOR TOTAL -- ============================================================ IF v_valido THEN SELECT COALESCE(SUM(pedi_vltotal), 0) INTO v_soma_itens FROM ipedi.pedi WHERE pedi_ped_codigo = rec_ped.ped_codigo; IF ABS(v_soma_itens - rec_ped.pvvltotal) > 0.05 THEN v_resposta := v_resposta || chr(10) || 'AVISO: Valor do cabecalho diverge da soma dos itens' || chr(10) || 'Cabecalho: ' || TO_CHAR(rec_ped.pvvltotal, 'FM999999990.00') || chr(10) || 'Soma itens: ' || TO_CHAR(v_soma_itens, 'FM999999990.00') || chr(10) || 'Valor corrigido para soma dos itens.'; END IF; END IF; -- ============================================================ -- PROCESSAMENTO DOS ITENS -- ============================================================ IF v_valido THEN SELECT nextval('pv_pvcod_seq') INTO v_pvcod; v_resposta := v_resposta || chr(10) || 'Pedido no ERP.....: ' || v_pvcod || chr(10); INSERT INTO pv( pvcod, pvcadusuparcod, pvcadhorario, pvacao, pvnumped, pvempparcod, pvcanal, pvsta, pvcliparcod, pvopnfcod, pvplpgcod, pvtccod, pvvltotal, pvvltotalate, pvvltotalatecar, pvindice, pvrcaparcod, pvobsped, pvobsnf, pvpedcli, pvdtprog, pvfvresposta, pvbloq, pvbloqusuparcod, pvbloqhorario, pvbloqobs, pvsit, pv_latitude, pv_longitude, pv_accuracy, pv_timestamp_geo, pvrefpvcod ) VALUES ( v_pvcod, rec_ped.pvcadusuparcod, rec_ped.pvcadhorario, rec_ped.pvacao, v_pvcod, rec_ped.pvempparcod, rec_ped.pvcanal, v_sta, rec_ped.pvcliparcod, rec_ped.pvopnfcod, rec_ped.pvplpgcod, rec_ped.pvtccod, v_soma_itens, v_soma_itens, v_soma_itens, rec_ped.pvindice, rec_ped.pvrcaparcod, rec_ped.pvobsped, rec_ped.pvobsnf, rec_ped.pvpedcli, rec_ped.pvdtprog, v_resposta, v_bloq, v_bloqusuparcod, v_bloqhorario, v_bloqobs, v_sit, rec_ped.pvlatitude, rec_ped.pvlongitude, rec_ped.pvaccuracy, rec_ped.pvtimestamp_geo, rec_ped.ped_codigo ); FOR rec_item IN SELECT 'IMPORTADO PELO THUNDERAPI' AS pviacao, 'FV' AS pvicanal, pedi_procod AS pviprocod, pedi_embcod AS pviuvecod, uvedes AS pviuvedes, uveun AS pviuveun, uvemult AS pviuvemult, pedi_qt AS pviqtde, (pedi_vltotal / NULLIF(pedi_qt, 0)) AS pvivlven, pedi_vltotal AS pvivltotal, COALESCE(pedi_promcod, 0) AS pvipromcod, COALESCE(pedi_descqtdecod, 0) AS pvidescqtdecod, pedi_vlst AS pvivlst, pedi_vlipi AS pvivlipi, ROW_NUMBER() OVER (ORDER BY pedi_codigo) AS pviseq FROM ipedi.pedi JOIN uve ON pedi_procod = uveprocod AND pedi_embcod = uvecod WHERE pedi_ped_codigo = rec_ped.ped_codigo LOOP v_item_aceito := TRUE; v_dq_vlven := NULL; -- PRODUTO ATIVO E DISPONÍVEL NO FV SELECT estdispfv, estforalinha INTO v_estdispfv, v_estforalinha FROM est WHERE estprocod = rec_item.pviprocod AND estempparcod = rec_ped.pvempparcod; IF v_estforalinha = 'S' THEN v_item_aceito := FALSE; v_resposta := v_resposta || chr(10) || 'ITEM CORTADO: ' || rec_item.pviprocod || ' - Produto fora de linha'; ELSIF v_estdispfv = 'N' THEN v_item_aceito := FALSE; v_resposta := v_resposta || chr(10) || 'ITEM CORTADO: ' || rec_item.pviprocod || ' - Produto nao disponivel para Forca de Vendas'; END IF; IF v_item_aceito THEN -- ESTOQUE E PREÇO SELECT COALESCE(TRUNC((estqtde - estqtderes - estqtdebloq - estqtdepend - estqtdediverg) / rec_item.pviuvemult), 0), COALESCE(estcustocompra, 0), COALESCE(estcustoreal, 0), estcalcdebcred INTO v_qtdedisp, v_custocompra, v_custoreal, v_calcDebCred FROM est WHERE estprocod = rec_item.pviprocod AND estempparcod = rec_ped.pvempparcod; SELECT fprvltab, fprvlven, fprembcod, fprpercdesctab, fprpercaumtab INTO v_vltab, v_vlven, v_vltab_embcod, v_fprpercdesctab, v_fprpercaumtab FROM f_preco( rec_ped.lpcod, rec_ped.pvrcaparcod, rec_ped.pvcliparcod, rec_ped.pvplpgcod, rec_ped.pvtccod, '%' || rec_item.pviprocod::text || '%', 100 ) WHERE fprprocod = rec_item.pviprocod AND fprembcod = rec_item.pviuvecod LIMIT 1; IF NOT FOUND THEN SELECT fprvltab, fprvlven, fprembcod, fprpercdesctab, fprpercaumtab INTO v_vltab, v_vlven, v_vltab_embcod, v_fprpercdesctab, v_fprpercaumtab FROM f_preco( rec_ped.lpcod, rec_ped.pvrcaparcod, rec_ped.pvcliparcod, rec_ped.pvplpgcod, rec_ped.pvtccod, '%' || rec_item.pviprocod::text || '%', 100 ) WHERE fprprocod = rec_item.pviprocod LIMIT 1; IF FOUND THEN v_resposta := v_resposta || chr(10) || 'AVISO: produto ' || rec_item.pviprocod || ' emb.enviada=' || rec_item.pviuvecod || ' emb.usada=' || v_vltab_embcod || ' (divergencia de embalagem)'; END IF; END IF; IF v_vltab IS NULL THEN v_item_aceito := FALSE; v_resposta := v_resposta || chr(10) || 'ITEM SEM PRECO: ' || rec_item.pviprocod || ' (livro ' || rec_ped.lpcod || ') - Item cortado'; ELSE -- VALIDAÇÃO DE PREÇO IF rec_item.pvidescqtdecod > 0 THEN SELECT dqiqtde, dqiqtate, dqitaxa, dqivl INTO v_dq_qtde, v_dq_qtate, v_dq_taxa, v_dq_vl FROM descqtdei JOIN descqtde ON dqidqcod = dqcod WHERE dqcod = rec_item.pvidescqtdecod AND dqsta = 'A' AND dqfv = 'S' AND date(now()) BETWEEN dqDtIni AND dqDtFim AND dqiqtde <= rec_item.pviqtde AND dqiqtate >= rec_item.pviqtde LIMIT 1; IF NOT FOUND THEN v_item_aceito := FALSE; v_resposta := v_resposta || chr(10) || 'ITEM CORTADO: ' || rec_item.pviprocod || ' - Politica de desconto por qtde nao encontrada ou fora da faixa' || ' (cod: ' || rec_item.pvidescqtdecod || ' qtde: ' || TO_CHAR(rec_item.pviqtde, 'FM999999990.00') || ')'; ELSE IF v_dq_vl > 0 THEN v_dq_vlven := v_dq_vl; ELSE v_dq_vlven := ROUND(v_vltab - (v_vltab * v_dq_taxa / 100), 2); END IF; IF ROUND(rec_item.pvivlven, 2) <> ROUND(v_dq_vlven, 2) THEN v_item_aceito := FALSE; v_resposta := v_resposta || chr(10) || 'ITEM CORTADO: ' || rec_item.pviprocod || ' - Preco diverge da politica de desconto por qtde' || ' Enviado: ' || TO_CHAR(ROUND(rec_item.pvivlven, 2), 'FM999999990.00') || ' Esperado: ' || TO_CHAR(ROUND(v_dq_vlven, 2), 'FM999999990.00') || ' (raw env: ' || rec_item.pvivlven::text || ' raw esp: ' || v_dq_vlven::text || ')'; END IF; END IF; ELSIF rec_item.pvipromcod > 0 THEN SELECT promsta, promdtini, promdtfim INTO v_promsta, v_promdtini, v_promdtfim FROM promocao WHERE promcod = rec_item.pvipromcod LIMIT 1; IF NOT FOUND OR v_promsta <> 'A' THEN v_item_aceito := FALSE; v_resposta := v_resposta || chr(10) || 'ITEM CORTADO: ' || rec_item.pviprocod || ' - Promocao inexistente ou inativa' || ' (promcod: ' || rec_item.pvipromcod || ')'; ELSIF date(now()) NOT BETWEEN v_promdtini AND v_promdtfim THEN v_item_aceito := FALSE; v_resposta := v_resposta || chr(10) || 'ITEM CORTADO: ' || rec_item.pviprocod || ' - Promocao fora do periodo de vigencia' || ' (de: ' || to_char(v_promdtini, 'DD/MM/YYYY') || ' ate: ' || to_char(v_promdtfim, 'DD/MM/YYYY') || ')'; ELSE -- Item com promoção: limites calculados sobre o preço PROMOCIONAL (v_vlven) IF v_vlven > 0 THEN vminpermitido := ROUND(ROUND(v_vlven, 2) * (1 - COALESCE(v_fprpercdesctab, 0) / 100), 2); vmaxpermitido := ROUND(ROUND(v_vlven, 2) * (1 + COALESCE(v_fprpercaumtab, 0) / 100), 2); IF ROUND(rec_item.pvivlven, 2) < vminpermitido THEN v_item_aceito := FALSE; v_resposta := v_resposta || chr(10) || 'ITEM CORTADO: ' || rec_item.pviprocod || ' - Preco ABAIXO do permitido (item com promocao)' || ' Venda: ' || TO_CHAR(ROUND(rec_item.pvivlven, 2), 'FM999999990.00') || ' Min: ' || TO_CHAR(vminpermitido, 'FM999999990.00'); /*ELSIF ROUND(rec_item.pvivlven, 2) > vmaxpermitido THEN v_item_aceito := FALSE; v_resposta := v_resposta || chr(10) || 'ITEM CORTADO: ' || rec_item.pviprocod || ' - Preco ACIMA do permitido (item com promocao)' || ' Venda: ' || TO_CHAR(ROUND(rec_item.pvivlven, 2), 'FM999999990.00') || ' Max: ' || TO_CHAR(vmaxpermitido, 'FM999999990.00');*/ END IF; END IF; END IF; ELSE -- SEM PROMOÇÃO E SEM DESCONTO QTDE: VALIDA MÍN/MÁX IF v_vltab > 0 THEN vminpermitido := ROUND(v_vltab * (1 - COALESCE(v_fprpercdesctab, 0) / 100), 2); vmaxpermitido := ROUND(v_vltab * (1 + COALESCE(v_fprpercaumtab, 0) / 100), 2); IF ROUND(rec_item.pvivlven, 2) < ROUND(v_vltab, 2) THEN IF ROUND(rec_item.pvivlven, 2) < vminpermitido THEN v_item_aceito := FALSE; v_resposta := v_resposta || chr(10) || 'ITEM CORTADO: ' || rec_item.pviprocod || ' - Preco ABAIXO do permitido' || ' Venda: ' || TO_CHAR(ROUND(rec_item.pvivlven, 2), 'FM999999990.00') || ' Min: ' || TO_CHAR(vminpermitido, 'FM999999990.00'); END IF; ELSIF ROUND(rec_item.pvivlven, 2) > ROUND(v_vltab, 2) THEN IF ROUND(rec_item.pvivlven, 2) > vmaxpermitido THEN v_item_aceito := FALSE; v_resposta := v_resposta || chr(10) || 'ITEM CORTADO: ' || rec_item.pviprocod || ' - Preco ACIMA do permitido' || ' Venda: ' || TO_CHAR(ROUND(rec_item.pvivlven, 2), 'FM999999990.00') || ' Max: ' || TO_CHAR(vmaxpermitido, 'FM999999990.00'); END IF; END IF; END IF; END IF; -- VALIDAÇÃO DE ESTOQUE IF v_item_aceito THEN IF v_qtdedisp >= rec_item.pviqtde THEN v_qtdeate := rec_item.pviqtde; v_qtdeatecar := rec_item.pviqtde; ELSIF v_qtdedisp > 0 THEN v_resposta := v_resposta || chr(10) || 'CORTE: ' || rec_item.pviprocod || ' Q.Ven: ' || TO_CHAR(rec_item.pviqtde, 'FM999999990.00') || ' Q.Ate: ' || TO_CHAR(v_qtdedisp, 'FM999999990.00'); IF NOT v_tratou_corte THEN IF v_conf_corte = 'P' THEN IF v_sta = 'AA' THEN v_sta := 'AP'; END IF; v_resposta := v_resposta || chr(10) || '** Pedido sujeito a aprovacao por ocorrencia de cortes.'; ELSIF v_conf_corte = 'R' THEN v_item_aceito := FALSE; v_valido := FALSE; v_resposta := v_resposta || chr(10) || '** PEDIDO RECUSADO por ocorrencia de cortes.'; EXIT; END IF; v_tratou_corte := TRUE; END IF; v_qtdeate := v_qtdedisp; v_qtdeatecar := v_qtdedisp; ELSE v_resposta := v_resposta || chr(10) || 'SEM ESTOQUE: ' || rec_item.pviprocod || ' Q.Ven: ' || TO_CHAR(rec_item.pviqtde, 'FM999999990.00') || ' Q.Ate: 0.00'; IF v_conf_recusa_item_sem_est = 'S' THEN v_item_aceito := FALSE; v_qtdeate := 0; v_qtdeatecar := 0; v_resposta := v_resposta || ' - Item recusado'; ELSE v_qtdeate := rec_item.pviqtde; v_qtdeatecar := rec_item.pviqtde; v_resposta := v_resposta || ' - Aceito sem estoque (config desmarcada)'; END IF; IF v_item_aceito AND NOT v_tratou_corte THEN IF v_conf_corte = 'P' THEN IF v_sta = 'AA' THEN v_sta := 'AP'; END IF; v_resposta := v_resposta || chr(10) || '** Pedido sujeito a aprovacao por ocorrencia de cortes.'; ELSIF v_conf_corte = 'R' THEN v_item_aceito := FALSE; v_valido := FALSE; v_resposta := v_resposta || chr(10) || '** PEDIDO RECUSADO por ocorrencia de cortes.'; EXIT; END IF; v_tratou_corte := TRUE; END IF; END IF; END IF; END IF; END IF; -- Base deb/cred e acúmulo IF (coalesce(rec_item.pvipromcod,0) > 0) THEN v_basedebcred := v_vlven; v_vltab := v_vlven; ELSIF v_calcDebCred = 'S' THEN v_basedebcred := v_vltab; ELSE v_basedebcred := rec_item.pvivlven; END IF; v_soma_pedido := v_soma_pedido + rec_item.pvivltotal; v_soma_pedido_ate := v_soma_pedido_ate + CASE WHEN v_item_aceito THEN (v_qtdeate * rec_item.pvivlven) + rec_item.pvivlst + rec_item.pvivlipi ELSE 0 END; v_soma_basedebcred := v_soma_basedebcred + CASE WHEN v_item_aceito THEN v_qtdeate * v_basedebcred ELSE 0 END; IF v_item_aceito THEN v_item_ate := v_item_ate + 1; INSERT INTO pvi( pvicadusuparcod, pvicadhorario, pviacao, pvicanal, pvipvempparcod, pvipvcod, pviprocod, pviuvecod, pviuvedes, pviuveun, pviuvemult, pviqtde, pviqtdeate, pviqtdeatecar, pvivltab, pvivlven, pvivltotal, pvicustocompra, pvicustoreal, pvipromcod, pvidescqtdecod, pvivlst, pvivlipi, pviseq, pvibasedebcred ) VALUES ( rec_ped.pvcadusuparcod, rec_ped.pvcadhorario, rec_item.pviacao, rec_item.pvicanal, rec_ped.pvempparcod, v_pvcod, rec_item.pviprocod, rec_item.pviuvecod, rec_item.pviuvedes, rec_item.pviuveun, rec_item.pviuvemult, rec_item.pviqtde, v_qtdeate, v_qtdeatecar, v_vltab, rec_item.pvivlven, rec_item.pvivltotal, v_custocompra, v_custoreal, NULLIF(rec_item.pvipromcod, 0), NULLIF(rec_item.pvidescqtdecod, 0), rec_item.pvivlst, rec_item.pvivlipi, rec_item.pviseq, v_basedebcred ); v_resposta := v_resposta || chr(10) || 'ITEM: ' || LPAD(rec_item.pviprocod::text, 6) || ' | Qt: ' || TO_CHAR(rec_item.pviqtde, 'FM999999990.00') || ' | Vl.Unit: ' || TO_CHAR(rec_item.pvivlven, 'FM999999990.00') || ' | Total: ' || TO_CHAR(rec_item.pvivltotal, 'FM999999990.00') || CASE WHEN rec_item.pvipromcod > 0 THEN ' | PROMO: ' || rec_item.pvipromcod::text ELSE '' END || CASE WHEN rec_item.pvidescqtdecod > 0 THEN ' | DESC.QT: ' || rec_item.pvidescqtdecod::text ELSE '' END; END IF; END LOOP; -- ============================================================ -- TOTALIZADOR -- ============================================================ v_resposta := v_resposta || chr(10) || '---' || chr(10) || 'Itens atendidos..: ' || v_item_ate || chr(10) || 'Valor atendido...: ' || TO_CHAR(v_soma_pedido_ate, 'FM999999990.00'); -- ============================================================ -- CONSULTA SALDO DÉB/CRÉD DO VENDEDOR -- Busca a data de início do período configurada no RCA, -- depois obtém saldo atual (dc_saldo) e limite especial (dc_limite) -- em uma única chamada à f_calc_debcred. -- ============================================================ SELECT COALESCE(rca_d_debcred, '1900-01-01') INTO v_dc_dini FROM rca WHERE rcaparcod = rec_ped.pvrcaparcod; SELECT COALESCE(dc_saldo, 0), COALESCE(dc_limite, 0) INTO v_fdebcred, v_dc_limite FROM f_calc_debcred(rec_ped.pvempparcod, rec_ped.pvrcaparcod, v_dc_dini, NULL, NULL) WHERE dc_rca_cod = rec_ped.pvrcaparcod; v_resposta := v_resposta || chr(10) || 'Deb/Cred Vendedor: ' || TO_CHAR(v_fdebcred, 'FM999999990.00') || chr(10) || 'Limite Especial..: ' || TO_CHAR(v_dc_limite, 'FM999999990.00'); -- ============================================================ -- NENHUM ITEM ATENDIDO -- ============================================================ IF v_item_ate = 0 THEN v_valido := FALSE; v_resposta := v_resposta || chr(10) || '** PEDIDO RECUSADO **' || chr(10) || 'Motivo: Nenhum item atendido'; END IF; -- ============================================================ -- LIMITE DE CRÉDITO -- ============================================================ IF v_valido THEN SELECT f_calc_clilimdisp INTO v_clilimdisp FROM f_calc_clilimdisp(rec_ped.pvempparcod, rec_ped.pvcliparcod); IF v_soma_pedido_ate > v_clilimdisp THEN IF v_conf_recusa_lim_cred = 'S' THEN v_valido := FALSE; v_resposta := v_resposta || chr(10) || '** PEDIDO RECUSADO **' || chr(10) || 'Motivo: Limite de credito excedido' || chr(10) || 'Valor atendido...: ' || TO_CHAR(v_soma_pedido_ate, 'FM999999990.00') || chr(10) || 'Limite disponivel: ' || TO_CHAR(v_clilimdisp, 'FM999999990.00'); ELSE IF v_sta = 'AA' THEN v_sta := 'AP'; END IF; v_resposta := v_resposta || chr(10) || '** Pedido sujeito a aprovacao, limite de credito excedido.' || chr(10) || 'Valor atendido...: ' || TO_CHAR(v_soma_pedido_ate, 'FM999999990.00') || chr(10) || 'Limite disponivel: ' || TO_CHAR(v_clilimdisp, 'FM999999990.00'); END IF; END IF; END IF; -- ============================================================ -- VALIDAÇÃO 11: VALOR MÍNIMO BOLETO -- ============================================================ IF v_valido AND v_tctdoc = 'BO' THEN SELECT GREATEST(COALESCE(plpgnumparc, 1), 1) INTO v_qtdeparcelas FROM plpg WHERE plpgcod = rec_ped.pvplpgcod; v_valor_parcela := ROUND(COALESCE(v_soma_pedido_ate, 0) / NULLIF(v_qtdeparcelas, 0), 2); IF COALESCE(v_cli_valorminbol, 0) > 0 AND v_valor_parcela < v_cli_valorminbol THEN v_valido := FALSE; v_resposta := v_resposta || chr(10) || '** PEDIDO RECUSADO **' || chr(10) || 'Motivo: As parcelas deste pedido estao abaixo do valor minimo para boleto' || chr(10) || 'Numero de parcelas..: ' || v_qtdeparcelas || chr(10) || 'Valor das parcelas..: ' || TO_CHAR(v_valor_parcela, 'FM999999990.00') || chr(10) || 'Valor minimo boleto.: ' || TO_CHAR(v_cli_valorminbol, 'FM999999990.00'); END IF; IF v_valido AND COALESCE(v_soma_pedido_ate, 0) > 0 THEN v_valor_despesas := ROUND(COALESCE(v_clidespbol, 0) * v_qtdeparcelas, 2); IF v_qtdeparcelas > 0 AND v_soma_pedido_ate < v_valor_despesas THEN v_valido := FALSE; v_resposta := v_resposta || chr(10) || '** PEDIDO RECUSADO **' || chr(10) || 'Motivo: O valor atendido neste pedido e insuficiente para pagamento boleto' || chr(10) || 'Valor atendido.....: ' || TO_CHAR(v_soma_pedido_ate, 'FM999999990.00') || chr(10) || 'Despesas boleto....: ' || TO_CHAR(v_valor_despesas, 'FM999999990.00'); END IF; END IF; END IF; -- ============================================================ -- VALIDAÇÃO 9-B: % MÁXIMO DE TROCA -- (executada após loop de itens para que v_soma_pedido_ate esteja disponível) -- ============================================================ IF v_valido AND v_eh_troca THEN v_cli_perc_bon_troca := 0; v_ped_ref_vltotalatecar := 0; v_pvreftotal := 0; v_pedrefcod := NULL; v_valor_limite_troca := 0; IF NULLIF(TRIM(COALESCE(rec_ped.ped_referenciaerp, '')), '') IS NULL THEN v_valido := FALSE; v_resposta := v_resposta || chr(10) || '** PEDIDO RECUSADO **' || chr(10) || 'Motivo: Pedido de troca sem pedido de referencia informado.'; ELSE BEGIN v_pedrefcod := NULLIF(TRIM(COALESCE(rec_ped.ped_referenciaerp, '')), '')::INTEGER; EXCEPTION WHEN OTHERS THEN v_pedrefcod := NULL; END; IF v_pedrefcod IS NULL THEN v_valido := FALSE; v_resposta := v_resposta || chr(10) || '** PEDIDO RECUSADO **' || chr(10) || 'Motivo: Pedido de referencia invalido para troca.'; ELSE SELECT COALESCE(cli_perc_bon_troca_pv, 0) INTO v_cli_perc_bon_troca FROM cli WHERE cliparcod = rec_ped.pvcliparcod; IF COALESCE(v_cli_perc_bon_troca, 0) <= 0 THEN v_valido := FALSE; v_resposta := v_resposta || chr(10) || '** PEDIDO RECUSADO **' || chr(10) || 'Motivo: Nenhuma configuracao de % de Troca encontrada para o cliente.'; ELSE SELECT COALESCE(p.pvvltotalatecar, 0) INTO v_ped_ref_vltotalatecar FROM pv p WHERE p.pvcod = v_pedrefcod AND p.pvsta IN ('AA','AP') LIMIT 1; IF COALESCE(v_ped_ref_vltotalatecar, 0) <= 0 THEN v_valido := FALSE; v_resposta := v_resposta || chr(10) || '** PEDIDO RECUSADO **' || chr(10) || 'Motivo: Pedido Referencia recusado, inexistente ou sem valor valido no ERP.'; ELSE v_valor_limite_troca := ROUND( (v_ped_ref_vltotalatecar * v_cli_perc_bon_troca / 100.0) , 2); v_resposta := v_resposta || chr(10) || '---' || chr(10) || 'Informacoes da Troca:' || chr(10) || 'Ped. Referencia.......: ' || v_pedrefcod::TEXT || chr(10) || 'Vlr. Ped. Referenciado: ' || TO_CHAR(v_ped_ref_vltotalatecar, 'FM999999990.00') || chr(10) || 'Percentual permitido..: ' || TO_CHAR(v_cli_perc_bon_troca, 'FM999999990.00') || '%' || chr(10) || 'Vlr. Max. Permitido...: ' || TO_CHAR(v_valor_limite_troca, 'FM999999990.00') || chr(10) || 'Vlr. da Troca.........: ' || TO_CHAR(v_soma_pedido_ate, 'FM999999990.00'); IF ROUND(v_soma_pedido_ate, 2) > v_valor_limite_troca THEN v_valido := FALSE; v_resposta := v_resposta || chr(10) || '** PEDIDO RECUSADO **' || chr(10) || 'Motivo: Valor da Troca ultrapassa o limite percentual permitido sobre o pedido referenciado.'; ELSE v_resposta := v_resposta || chr(10) || 'Troca dentro do limite permitido.'; END IF; END IF; END IF; END IF; END IF; END IF; -- ============================================================ -- VALIDAÇÃO 12: DÉBITO/CRÉDITO DO RCA -- Saldo disponível = Limite Especial (dc_limite) + Saldo atual (dc_saldo) -- Bloqueia quando: (saldo_disponivel + debcred_pedido) < 0 -- ============================================================ IF v_valido THEN DECLARE v_opnftopnfcod VARCHAR(2); v_rcausadebcred TEXT; v_soma_basedcred NUMERIC(14,4); v_debcred_pedido NUMERIC(14,4); v_saldo_disponivel NUMERIC(14,4); BEGIN SELECT opnftopnfcod INTO v_opnftopnfcod FROM opnf WHERE opnfcod = rec_ped.pvopnfcod; SELECT COALESCE(rcausadebcred, 'N') INTO v_rcausadebcred FROM rca WHERE rcaparcod = rec_ped.pvrcaparcod; IF v_rcausadebcred = 'S' AND v_opnftopnfcod IN ('VV', 'VE') THEN v_soma_basedcred := v_soma_basedebcred; IF v_soma_basedcred = 0 THEN v_soma_basedcred := v_soma_pedido_ate * 2; END IF; v_debcred_pedido := v_soma_pedido_ate - v_soma_basedcred; -- v_dc_limite e v_fdebcred já foram obtidos da f_calc_debcred acima v_saldo_disponivel := v_dc_limite + v_fdebcred; v_resposta := v_resposta -- || chr(10) || 'Saldo Disponivel.: ' || TO_CHAR(v_saldo_disponivel, 'FM999999990.00') || chr(10) || 'Deb/Cred Pedido..: ' || TO_CHAR(v_debcred_pedido, 'FM999999990.00'); IF (v_saldo_disponivel + v_debcred_pedido) < 0 THEN v_valido := FALSE; v_resposta := v_resposta || chr(10) || '** PEDIDO RECUSADO **' || chr(10) || 'Motivo: Deb/Cred do pedido ultrapassa o limite disponivel do vendedor.' || chr(10) || 'Deb/Cred Vendedor: ' || TO_CHAR(v_fdebcred, 'FM999999990.00') || chr(10) || 'Limite Especial..: ' || TO_CHAR(v_dc_limite, 'FM999999990.00') -- || chr(10) || 'Saldo Disponivel.: ' || TO_CHAR(v_saldo_disponivel, 'FM999999990.00') || chr(10) || 'Valor Tabela......: ' || TO_CHAR(v_soma_basedcred, 'FM999999990.00') || chr(10) || 'Valor Atendido....: ' || TO_CHAR(v_soma_pedido_ate, 'FM999999990.00') || chr(10) || 'Deb/Cred Pedido..: ' || TO_CHAR(v_debcred_pedido, 'FM999999990.00'); -- || chr(10) || 'Saldo Resultante.: ' || TO_CHAR(v_saldo_disponivel + v_debcred_pedido, 'FM999999990.00'); END IF; END IF; END; END IF; -- ============================================================ -- Atualiza PV com resposta e status finais -- ============================================================ UPDATE pv SET pvfvresposta = v_resposta, pvfvcodrem = rec_ped.pvfvcodrem, pvsta = CASE WHEN v_valido THEN v_sta ELSE 'RP' END, pvsit = CASE WHEN v_valido THEN v_sit ELSE 'REPROVADO' END, pvvltotal = v_soma_pedido_ate, pvvltotalate = v_soma_pedido_ate, pvvltotalatecar = v_soma_pedido_ate, pvvldesc = ( SELECT CASE WHEN SUM(pvivltab * pviqtdeate) > SUM(pvivlven * pviqtdeate) THEN SUM(pvivltab * pviqtdeate) - SUM(pvivlven * pviqtdeate) ELSE -1 * (SUM(pvivlven * pviqtdeate) - SUM(pvivltab * pviqtdeate)) END FROM pvi WHERE pvipvcod = v_pvcod ) WHERE pvcod = v_pvcod; -- Se recusou após criar PV, remove registros para não deixar pedido inconsistente IF NOT v_valido THEN DELETE FROM pvi WHERE pvipvcod = v_pvcod; DELETE FROM pv WHERE pvcod = v_pvcod; v_pvcod := 0; END IF; END IF; END LOOP; -- ============================================================ -- RETORNO FINAL -- ============================================================ IF (v_pvcod > 0) AND ((SELECT COUNT(pviprocod) FROM pvi WHERE pvipvcod = v_pvcod) > 0) THEN UPDATE ipedi.ped SET ped_importado = 2, ped_obsretorno = v_resposta WHERE ped_codigo = p_pedcod; RETURN QUERY SELECT p_pedcod, v_pvcod::integer, v_pvcod::integer, v_resposta::text; ELSE v_resposta := v_resposta || chr(10) || '** PEDIDO RECUSADO **' || CASE WHEN v_bloqobs IS NOT NULL THEN chr(10) || 'Detalhe: ' || v_bloqobs ELSE '' END || chr(10) || 'Pedido Palm: ' || p_pedcod || chr(10) || 'Empresa: ' || p_empresa; UPDATE ipedi.ped SET ped_importado = 1, ped_obsretorno = v_resposta WHERE ped_codigo = p_pedcod; RETURN QUERY SELECT 0, 0::integer, 0::integer, v_resposta::text; END IF; RETURN; EXCEPTION WHEN OTHERS THEN RETURN QUERY SELECT 0, 0::integer, 0::integer, ('ERRO INTERNO: ' || SQLERRM)::text; END; $function$ ; -- Permissions ALTER FUNCTION public.f_processar_fv(int4, int4) OWNER TO postgres; GRANT ALL ON FUNCTION public.f_processar_fv(int4, int4) TO public; GRANT ALL ON FUNCTION public.f_processar_fv(int4, int4) TO postgres; ------------------------------------------------------------------------------------------------ ALTER TABLE public.nfi ADD nfidifalbc numeric(14, 4) NULL; ALTER TABLE public.nfi ALTER COLUMN nfidifalbc SET STORAGE MAIN; ALTER TABLE public.nfi ADD nfidifalaliq numeric(14, 4) NULL; ALTER TABLE public.nfi ALTER COLUMN nfidifalaliq SET STORAGE MAIN; ------------------------------------------------------------------------------------------------ -- DROP FUNCTION public.f_realizar_faturamento(int4, int4, int4, int4, timestamptz, timestamptz, int4, int4, int4); CREATE OR REPLACE FUNCTION public.f_realizar_faturamento(integer, integer, integer, integer, timestamp with time zone, timestamp with time zone, integer, integer, integer) RETURNS TABLE(frfatnfcod integer, frfatnfnum integer, frfatnfserie text, frfatmens text) LANGUAGE plpgsql AS $function$ declare /* 10/01/13 - KAYTON: Criação da função f_faturar 15/03/13 - KAYTON: Alteracao select pvi pra so selecionar itens com pviqtdeatecar > 0 where pviqtdeatecar>0 and pvipvempparcod=p_empresa and pvipvcod=p_pedido 21/03/13 - KAYTON: Implementacao da f_seqnf para obter o proximo numero de nf por opnf e empresa 16/07/13 - KAYTON: Implementacao cesta básica (Configuração prevista para tratar 1 item CB por pedido) 05/08/13 - KAYTON: Implementacao controle de estoque 02/09/13 - KAYTON: Implementacao da qtde reservada 10/10/13 - KAYTON: Implementacao do campo opnfcfop e opnfgt e aproveitamento de cred PIS/COFINS 11/10/13 - KAYTON: Tratamento coalesce -> icms,v_vicms,percipi 05/11/13 - KAYTON: Tratamento custo 07/11/13 - KAYTON: Corrigir erro de update em cprpg 26/11/13 - KAYTON: Implementacao do Lote (NAO FINALIZADO) 29/11/13 - KAYTON: Corrigir insert do estmv 06/12/13 - KAYTON: Customização do campo obs nf. Puxando de confobsnf 16/12/13 - KAYTON: Corrigir cliultnfserie 03/01/14 - KAYTON: Informações sobre compra do cliente considerar VI (rec_pv.opnftopnfcod IN ('VE','VI','VV')) 03/01/14 - KAYTON: Tratamento da rotina de recalcular comissão e atualização de dados NFIDET 26/03/14 - KAYTON: Tratamento de tributacao por produto 28/03/14 - KAYTON: Desconsiderar vldesc para total da nf, pois o item ja vem com desconto aplicado 31/03/14 - KAYTON: Suspender temporariamente o tratamento do vldesc 02/04/14 - KAYTON: Substituir opnfpis_cst para opnfcofins_cst no cálculo da base de dados cofins coalesce nos campos opnfpiscofins para validar corretamento com conteudo 'S' quando vazio no calculo de bcpis/bccofins 17/04/14 - KAYTON: Considerar campo coalesce(opnftipoemissaonf,'P') as opnftipoemissaonf, para nftipoemissao 04/05/14 - KAYTON: Implementação dos campos referentes à embalagem principal 09/05/14 - KAYTON: Ativação da regra controle de lote 26/05/14 - KAYTON: Gravar campo nfnumvol com o conteúdo sum(nfiqtde) 01/06/14 - KAYTON: Implementar regra CLILP - usar f_livro_do_cliente para localizar trib 25/06/14 - KAYTON: Calcular custocompra e custoreal multiplicado por uvemult e pviqtdeatecar 07/07/14 - KAYTON: Substituir uvemult por pviuvemult 07/07/14 - KAYTON: Adicionar bloco para calcular ipi/st quando pedido com índice 11/08/14 - KAYTON: Tratamento de tributacao por benefício fiscal associado ao cliente 11/08/14 - KAYTON: Alterar cobrança de acordo com parâmetro informado (b_boleto) e flag no tc (tc_per_alt_fat) 15/08/14 - KAYTON: Implementação do coalesce coalesce(tribbenefufdest,tribproufdest,tribufdest) corrigindo erro quando pedido bonificação enviando cfop de venda 15/09/14 - KAYTON: Implementação das regras de impressão tributação para OPNF ECF - opnftopnfcod='CF' 18/11/14 - KAYTON: Corrigindo regras para gravacao do lote 07/12/14 - KAYTON: Round 4 para qtde e round 2 para valores - Base de cálculo se aliq icms > 0 08/12/14 - KAYTON: Inclusão do campo pvtipofrete e nftipofrete, pviseq e nfiseq. Gravar pvalthorario, ação e usuário 02/04/15 - KAYTON: Inclusão da regra de gerar cprpg a partir da pvplpg (plano negociado) 02/04/15 - KAYTON: Gravar pvvol em nfvol 03/05/15 - KAYTON: 1. Corrigir diferença no valor total das parcelas (cprpg) em relação à nf. antes: cprvt/rec_pv.num_parc,--cprpgv numeric(14,4), depois: trunc(cprvt/rec_pv.num_parc,2),--cprpgv numeric(14,4), 2. Gerar primeira parcela do cprpg com ST. 16/05/15 - KAYTON: Adicionar novos campos em f_insert_estmv: parceiro, opnf operacao. 02/06/15 - KAYTON: Implementar faturamento Produto KIT. 05/06/15 - KAYTON: Alimentar cprpgparc com cprpgcod 08/06/15 - KAYTON: Alimentar nfibasedebcred com pvibasedebcred 21/07/15 - KAYTON: Implementar lote pelo pvilote 01/12/15 - RAUL: Alimentar transportadora com base no tipo de frete do pedido caso nao alimente transportadora ao faturar (p_transportadora) 04/12/15 - RAUL: Corrigir bugs do CPR e CPRPG e NFIVLVEN 1.data de vencimento do CPRPG (cprpgdvenc) agora é com base no parametro: p_horariosaida (v_datahorasaida), --> antes estava fixo now() 2.update cpr set cprdocnum=rec_seqnf.numero,cprdocserie=rec_seqnf.serie,cpr_notafiscal, agora com "v_nfcod", pois estava alterando registros em outras empresas 3.Alterado de round 2 para round 4 ao inserir nfivlunit (pvivlven). -->Kayton orientou estudarmos mais! 31/03/16 - KAYTON: Alimentar campos nfvlfrete e nfivlfrete referente a frete que vem de pvvlfrete e pvivlfrete respectivamente 28/06/16 - KAYTON: Alimentar campos nfiqtdefalta e nfiqtdecorte 06/07/16 - KAYTON: clicontricms para parcontricms -csosn para não contribuinte -tratamento temporario do parametro transportadora para contemplar regra lemos e demais -round pvltabunit e pvlven de 2 para 4 casas -lança despesa de boleto (clidespbol) na base de calculo do primeiro item 07/07/16 - KAYTON: Regra DIFFAL 07/07/16 - KAYTON: Corrigir cálculo despbol quando produto ST 07/07/16 - KAYTON: Cobrar despesa de boleto somente qd cobrança boleto e cliente marcado 20/01/17 - KAYTON: Implementação de efetivação automática de acordo com parâmetro confefetivarauto 27/03/17 - KAYTON: Implementação regra ST para não contribuinte 12/05/17 - KAYTON: Implementação dos campos pvvol,pvpesobruto,pvpesoliq,pvtranspparcod,pvdtentrega Considerando campo confusadtentregaparagerarfin para setar dtvenc tanto de plano negociado, qt plano pagamento 18/05/17 - KAYTON: Gravando trasnportadora do pedido (pvtranspparcod) na nf (nftranspcod) 04/07/17 - KAYTON: Obter Modelo do documento a partir do laymodelo (01, 55, 65) 13/07/17 - KAYTON: Gravar Aliq IVA em nfi (nfialiqiva) 20/02/18 - DAVID: calcular difal apenas se se a aliq de ICMS for > que 0 28/02/18 - DAVID: Tratar informações adicionais do pedido 05/03/18 - DAVID: Alterar busca do peso, alterado para UVE*qtde 07/03/18 - DAVID: Alterar para não calcular IPI em opérações SR 08/03/18 - DAVID: Alterar para calcular IPI em opérações ISENTO 01/06/18 - DAVID: Alterar para calcular IPI para seguir o informado na OPNF caso seja 'S' ou no cadastro do PRODUTO caso seja <> 'S' 30/07/18 - DAVID: Tratar FCP e FCPST alimentando os campos na NFI 05/09/18 - DAVID: multiplicar despesa de boleto pela quantidade de boletos 12/09/18 - DAVID: Travar IVA no faturamento 12/07/19 - DAVID: Alimentar campo nfialiqicmsefet 03/04/20 - DAVID: Alimentar campos nfi nfibcicmsefet e nfivlicmsefet 18/06/20 - DAVID: tratar aliqicmsefet para receber valor do gtperccredicmsbenef caso ele esteja preenchido 17/07/20 - DAVID: tratar campo pvipedcli 20/07/20 - DAVID: tratar opnfusaentregafutura para alimentar a tabela estcli 31/08/20 - DAVID: tratar opnfusaipinoicms para calcular o valor da base de ICMS + IPI 16/10/20 - DAVID: tratar base de fcp nfidifalbcfcpdest 12/11/20 - DAVID: Adicionar tratamento de m³: nfimetrocubico e nfmetrocubico 05/01/21 - DAVID: Não movimentar estoque para operações de entrega futura 12/01/21 - DAVID: tratar campo cli_perc_fin para dar desconto no documento 28/01/21 - David: tratar cbenef pelo codigo do GT 23/09/21 - David: Tratar opnf_nao_mov_est 28/07/22 - David: Tratar nfibcfcp e nfibcfcpst e o somatório do nfifcpvlqicmsst no nfvl 30/07/22 - David: criação dos campos v_vbcfcp e v_vbcfcpST e tratativa na inserção da NFI 11/08/22 - David: correção do valor do FCP ST baseado no v_vlfcpST 11/08/22 - David: correção do valor do ST baseado no v_vlfcpST 18/08/22 - David: correção do da base de ST para não somar o valor da base de FCP ST 18/08/22 - David: retirar o FCP ST do valor da ST, fiz de forma facil de retornar caso o contador da EXXA queira alterar novamente 02/09/22 - David: utilizar uvedes e uveun do cadastro do produto e não o salvo no pedido. -- feito para evitar que o dado não seja preenchido. 08/09/22 - David: Alimentar cprpgdescv com o valor calculado do % de desconto do cliente 13/09/22 - David: Voltar a regra do valor da CPR para salvar o valor cheio da nota 15/09/22 - David: Alteração na regra de desconto financeiro para considerar a ST daprimeira parcela 20/09/22 - David: Alteração na regra de desconto financeiro para considerar a ST daprimeira parcela 07/11/22 - David: Correção do calculo do v_vlfcpST para subtrair o valor da v_vlfcp 19/12/22 - David: Tratar o v_vicms_efet para receber o valor de redução do beneficio quando ele estiver presente no cadastro da empresa 27/12/22 - David: Correção do beneficio fiscal, para tratar os campos do grupo de tributação 23/01/22 - David: Tratar parcontricms <> N para verificar qual bloco da tributação será utilizada 08/03/23 - David: Tratar despbol para ser rateado em todos os produtos e ser considerado na base de ST verifica diferenca de despbol e joga no ultimo produto 21/06/23 - David: Envio de mensagem para o vendedor sempre que um pedido for faturado 31/06/23 - David: Correção da soma de despesa de boleto na ST 30/09/23 - David: Correção do v_baseicms para tratar a redução corretamente 18/10/23 - David: Correção da redução da base de ST 03/11/23 - David: Correção do valor de outras despesas, comentar o bloco que recalcula elas visto que o valor esta sendo lançado corretamente 13/11/23 - David: usar o campo conf_div_st_parcelas para verificar se divide a ST ou se mantem o calculo atual 11/04/24 - David: alimentar nfibcipi no momento de faturar 23/04/24 - David: corrigir nfivloutrasdesp para 2 casas decimais 09/07/24 - David: Criação da varialvel v_vlfcp para alimentar o valor de FCP baseado em um calculo em tempo real da base de ICMS 18/07/24 - David: alimentar o campo nfrefnfcod com o pvrefnfcod para a referencia de NFce 02/08/24 - David: - Correção na identação - criar campo v_vpro - tratar calculo da ST baseado no campo conf_usa_desconta_st_do_preco para que o sistema calcule o valor dos produtos baseado na precificação como valor final 12/09/24 - David: recalcular o valor da base de calculo de acordo com o novo valor do produto para os casos de v_DescontaStdoPreco = 'S' 13/09/24 - David: verifica se existe uyma diferença no valor sum(nfivl+nfivlicmsst+nfifcpvlqicmsst)-sum(round(nfivl,2)+round(nfivlicmsst,2)+round(nfifcpvlqicmsst,2) , caso exista, joga essa diferença no ultimo produto 09/10/24 - David: correção da aliquota de destino do DIFAL para usar 100% da aliquota e não mais subtrair a aliq interna 11/10/24 - David: correção do valor da ST quando não descontata do preço, para 2 casas decimais 11/12/24 - David: corrigir vicms quando opnfusaipinoicms = 'S' 11/08/25 - David: remover a validação de empresa do update do carregamento, pois podem ter pedidos de varias empresas em um unico carregamento. David: tratar tctaxacartao como adicional na parcela 02/09/25 - David: Correção do v_vlfcpST para considerar apenas se o valor da ST for maior que 0 26/09/25 - David: Tratar IBS e CBS, com a aprovação da Reforma Tributária (PEC 45/2019 e PEC 110/2019), está prevista a substituição de diversos tributos atuais pela criação de dois novos tributos. 05/12/25 - David: Tratar valor da base de ibs/cbs para usar o v_vproFinal 30/12/25 - David: correção do calculo do v_vlfcpst para usar o v_vlfcp ao inves do pvivlfcp 31/12/25 - David: tratativa do IBS/CBS para usar 2 casas 05/01/26 - David: tratar IBS/CBS para usar o valor da redução no calculo 06/01/26 - David: tratar v_BaseCalcIbsCbs para ser preenchida apenas se a aliq > 0 14/01/26 - David: tratar calculo da v_BaseCalcIbsCbs para seguir a nota tecnica NT_2025.002_v1.34_RTC_NF 10/04/26 - David: tratar base de pis/cofins para a nova nota tecnica que diz que produtos isentos tem 10% do valor de pis e cofins -------------------------------------------------------------------------------------------------------------------------------------------------------- select * from f_realizar_faturamento(100,1,37879,0,cast(now() as date),now(),3,0,0) select * from pv where pvcod = 37879 update pv set pvsta = 'AA' where pvcod = 34484 select * from pvi where pvipvcod = 34484 select * from nfi where nfinfcod = 35793 */ p_usuario ALIAS for $1;--integer 1001 p_empresa ALIAS for $2;--integer 191 p_pedido ALIAS for $3;--integer 843 p_boleto ALIAS for $4;--integer 9 - CAIXA p_dtemissao ALIAS for $5;--date now() p_horariosaida ALIAS for $6;--timestamp p_transportadora ALIAS for $7;--integer p_veiculo ALIAS for $8;--integer p_motorista ALIAS for $9;--integer rec_pv RECORD; rec_plpg RECORD; rec_seqnf RECORD; rec_mens RECORD; rec_insert_estmv RECORD; rec_insert_estlotemv RECORD; rec_pv_insert_estmv RECORD; rec_pv_insert_estlotemv RECORD; rec_pv_usacontrolelote RECORD; rec_efetauto RECORD; v_nfidet RECORD; v_erro INTEGER; num_parc INTEGER; v_nfcod INTEGER; v_menscod INTEGER; v_res INTEGER; v_cprcod INTEGER; v_agora TIMESTAMP; v_datahorasaida TIMESTAMP; v_pedido INTEGER; v_vnf numeric(14, 4); v_visento numeric(14, 4); v_vbasecalc numeric(14, 4); v_vicms numeric(14, 4); v_voutros numeric(14, 4); v_vipi numeric(14, 4); v_vbasecalcST numeric(14, 4); v_vlicmsST numeric(14, 4); v_vdesc numeric(14, 4); v_vbcfcp numeric(14, 4); v_vbcfcpST numeric(14, 4); v_vlfcpST numeric(14, 4); v_vbasecalc_efet numeric(14, 4); v_vicms_efet numeric(14, 4); v_inseriuCab BOOLEAN; v_confobsnf text; v_obsnf text; v_VERSAO text; v_efetauto text; v_cliestprocod integer; v_DivSt text; v_vlfcp numeric(14, 4); v_DescontaStdoPreco text; v_vpro numeric(14, 4); v_vproFinal numeric(14, 4); v_indice_st numeric(14, 4); v_ibsmun numeric(14, 4); v_ibsmun_bruto numeric(14, 4); v_ibsuf numeric(14, 4); v_ibsuf_bruto numeric(14, 4); v_cbs numeric(14, 4); v_cbs_bruto numeric(14, 4); v_BaseCalcIbsCbs numeric(14, 4); begin --************************************************************* -- VERSAO DA FUNCAO FATURAMENTO --************************************************************* v_VERSAO = 'FUNCAO DE FATURAMENTO v2025.09.26.1'; --************************************************************* -- VALIDAR DADOS ANTES DO FATURAMENTO --************************************************************* v_erro := 0; for rec_mens in select pedido, advertencia from f_validar_faturamento(p_empresa, p_pedido) loop return QUERY select 0::integer as nfcod, 0::integer as nfnum, ''::text as nfserie, rec_mens.advertencia; v_erro := 1; end loop; if v_erro > 0 then return; end if; --************************************************************* -- OBTER DATA HORA HOJE --************************************************************* select now() into v_agora; --************************************************************* -- OBTER DADOS PV --************************************************************* v_inseriuCab := false; /* Inserir nf somente 1 vez e não para cada item do laço. Dessa forma é possivel usar 1 sql. */ --************************************************************* -- OBTER DADOS PV/PVI --************************************************************* for rec_pv in select /* REGRA ESPECIFICA LEMOS - TEMPORARIA (07/06/2016) INI-------------*/ case when ( select parcnpjcpf from par where parcod = pvempparcod) in ('12941093000138', '00652008000213', '00652008000990', '00652008000302', '00652008000647', '00652008000132', '11476381000368', '12978703000178', '01623668000239', '11476381000287', '01623668000158', '00652008000728', '11476381000104') then case when coalesce(p_transportadora, 0)>0 then p_transportadora --se informar transportadora when coalesce(p_transportadora, 0)= 0 and pvtipofrete = '0' then pvempparcod --se nao informar, 0=EMITENTE when coalesce(p_transportadora, 0)= 0 and pvtipofrete = '1' then pvcliparcod --se nao informar, 1=DESTINATARIO else p_transportadora end else case when coalesce(pvtranspparcod, 0)>0 then pvtranspparcod else p_transportadora end end as transpcod, /* REGRA ESPECIFICA LEMOS - TEMPORARIA (07/06/2016) FIM-------------*/ case when ( select tctdoc from tc where tccod = pvtccod)= 'BO' then coalesce(round((clidespbol * coalesce(plpgnumparc, 1))/ count(pviprocod) over (order by 1), 2), 0) else 0 end as despbol, pvempparcod, pvcod, pvsta, pvplpgcod, case when cast(p_boleto as integer)>0 and (select tc_per_alt_fat from tc where tccod = pvtccod)= 'S' then p_boleto else pvtccod end as pvtccod, pvcliparcod, pvopnfcod, pvrcaparcod, pvrcaauxparcod, pvsupparcod, pvcarcod, pvobsnf, pvindice, pvipvempparcod, pvipvcod, tipoproduto, kitprocod, pviprocod, --embalagem de venda pviuvecod, (select uvedes from uve where uveprocod = pviprocod and uvecod = pviuvecod) as pviuvedes, (select uveun from uve where uveprocod = pviprocod and uvecod = pviuvecod) as pviuveun, pviuvemult, pviqtde, pviqtdeate, pviqtdeatecar, pvivltab, pvibasedebcred, pvivlven, coalesce(pviqtde, 0)-coalesce(pviqtdeate, 0) as qtdefalta, coalesce(pviqtdeate, 0)-coalesce(pviqtdeatecar, 0) as qtdecorte, --embalagem principal (select uvecod from uve where uvetipo = 'P' and uveprocod = pviprocod limit 1) as puvecod, (select uvedes from uve where uvetipo = 'P' and uveprocod = pviprocod limit 1) as puvedes, (select uveun from uve where uvetipo = 'P' and uveprocod = pviprocod limit 1) as puveun, (select uvemult from uve where uvetipo = 'P' and uveprocod = pviprocod limit 1) as puvemult, --QT_PRINCIPAL=Qt.vendida*mult_venda/mult_principal round(pviqtdeatecar * pviuvemult /(select uvemult from uve where uvetipo = 'P' and uveprocod = pviprocod limit 1), 4) as pqtde, round(pvivltab / pviuvemult *(select uvemult from uve where uvetipo = 'P' and uveprocod = pviprocod limit 1), 4) as pvltabunit, round(pvivlven / pviuvemult *(select uvemult from uve where uvetipo = 'P' and uveprocod = pviprocod limit 1), 4) as pvlven, coalesce(prouvenf, 'V') as uvenf, pvivltotal, pviqtdeatecar *(pvivltab-pvivlven) as vldesc, parcontricms, regtribccsacod, opnfsta, opnf_conta_id, opnf_cc_id, opnfcpr, opnfesp, opnftopnfcod, coalesce(opnftipoemissaonf, 'P') as opnftipoemissaonf, case when opnfpiscofins = 'S' then opnfpis else cstpiscofins_aliq_pis end pisaliq, case when opnfpiscofins = 'S' then opnfpis_cst else estcstpiscofinscod end piscst, case when opnfpiscofins = 'S' then opnfpis_aliqvalor else estvlpautapis end pisvlpauta, --case when opnfpiscofins='S' then opnfpis_percred else gtfpispercred end pispercred, case when opnfpiscofins = 'S' then opnfcofins else cstpiscofins_aliq_cofins end cofinsaliq, case when opnfpiscofins = 'S' then opnfcofins_cst else estcstpiscofinscod end cofinscst, case when opnfpiscofins = 'S' then opnfcofins_aliqvalor else estvlpautacofins end cofinsvlpauta, --case when opnfpiscofins='S' then opnfcofins_percred else gtfcofinspercred end cofinspercred, --Valores PIS/COFINS (Base de calculo = Vl.Operacao - Vl.Desc) case when (coalesce(opnfpiscofins, '')= 'S' and coalesce(opnfpis_cst, '') in ('01', '06')) then pvivltotal when (coalesce(opnfpiscofins, '')<> 'S' and coalesce(estcstpiscofinscod, '') in ('01', '06')) then pvivltotal else 0 end as bcpis, case when (coalesce(opnfpiscofins, '')= 'S' and coalesce(opnfcofins_cst, '') in ('01', '06')) then pvivltotal when (coalesce(opnfpiscofins, '')<> 'S' and coalesce(estcstpiscofinscod, '') in ('01', '06')) then pvivltotal else 0 end as bccofins, 0 as bcqtpis,--pendente para produto com pauta 0 as bcqtcofins,--pendente para produto com pauta gtcod, gtdes, case when parcontricms <> 'N' then estvlpautaicms else estvlpautaicmsncontrib end as pauta, case when parcontricms <> 'N' then coalesce(gtpercredbc,0) else coalesce(gtncontribpercredbc,0) end as percrbcicms, case when opnftopnfcod = 'CF' then gtecfaliqicms else case when parcontricms = 'S' then gtaliqicms else gtncontribaliqicms end end as aliqicms, case when opnftopnfcod = 'CF' then gtecfaliqicms when gtperccredicmsbenef > 0 then gtperccredicmsbenef when parcontricms <> 'N' then gtaliqefet else gtncontribaliqefet end as aliqicmsefet, case when opnftopnfcod = 'CF' then gtecfcstcod else case when parcontricms <> 'N' then gtcstcod else gtncontribcstcod end end as cst, --case when parcontricms='S' then gtcfopcod else gtncontribcfopcod end as cfopcod, --se utilizar CFOP de OPNF case when opnftopnfcod = 'CF' then gtecfcfopcod else case when opnfcfop = 'S' and coalesce(tribbenefuforig, tribprouforig, tribuforig)= coalesce(tribbenefufdest, tribproufdest, tribufdest) then opnfcfopcode when opnfcfop = 'S' and coalesce(tribbenefuforig, tribprouforig, tribuforig)<> coalesce(tribbenefufdest, tribproufdest, tribufdest) and parcontricms = 'S' then opnfcfopcodi when opnfcfop = 'S' and coalesce(tribbenefuforig, tribprouforig, tribuforig)<> coalesce(tribbenefufdest, tribproufdest, tribufdest) and parcontricms <> 'S' then opnfcfopcodincontricms else case when parcontricms <> 'N' then gtcfopcod else gtncontribcfopcod end end end as cfopcod, case when parcontricms <> 'N' then gtmodalidbcicms else gtncontribmodalidbcicms end as modbcicms, case when parcontricms <> 'N' then gtisento else gtisento end as isento, case when coalesce(opnfipi, '')= 'S' then opnfcstipi else estcstipicod end as cstipi, case when coalesce(opnfipi, '')= 'S' then opnfaliqipi else estaliqipi end as percipi, --FCP case when coalesce(gtfcpaliqicms, 0) > 0 then gtfcpaliqicms else 0 end as fcpaliqicms, case when coalesce(gtfcpaliqicms, 0) > 0 then ((pvivltotal * gtfcpaliqicms)/ 100) else 0 end as fcpvlqicms, --FCP ST case when coalesce(gtfcpaliqicmsst, 0) > 0 then gtfcpaliqicmsst else 0 end as fcpaliqicmsst, case when coalesce(gtfcpaliqicmsst, 0) > 0 then ((pvivltotal * gtfcpaliqicmsst)/ 100) else 0 end as fcpvlqicmsst, --ST case when parcontricms <> 'N' then coalesce(estvlpautast, 0) else cast(0 as numeric) end as pautaret, case when parcontricms <> 'N' then coalesce(gtstaliqicms, 0) else cast(0 as numeric) end as aliqicmsret, case when parcontricms <> 'N' then coalesce(gtstpercredbc, 0) else cast(0 as numeric) end as percrbcicmsret, case when parcontricms <> 'N' then coalesce(gtstiva, 0) else cast(0 as numeric) end as aliqiva, case when parcontricms <> 'N' then coalesce(gtstmodalidbcicms, 0) else cast(0 as integer) end as modbcicmsret, --por enquanto não vamos tratar operação para não contribuinte, visto que não deve ter essa diferenciação (IBS/CBS) 26/09/2025 gtclasstribcod, --IBS MUN gtibsaliqmun, gtibspercredmun, --IBS UF gtibsaliquf, gtibspercreduf, -- CBS gtcbsaliq, gtcbspercred, gtmensagem, gtlegenda, gtpercdescisencaocond, -- NÃO CONTRIBUINTE case when parcontricms <> 'N' then gtcsosncod else gtncontribcsosncod end as gtcsosncod, case when parcontricms <> 'N' then gtperccredicmssn else gtncontribperccredicmssn end as gtpCredSN, --calculado round((pviqtdeatecar * pvivlven)*(case when parcontricms <> 'N' then gtperccredicmssn else gtncontribperccredicmssn end)/ 100, 2) as vCredICMSSN, (select fpeforparcod from fpe where fpeprocod = pviprocod and pvipvempparcod = fpeempparcod and fpetipo = 'P' limit 1) as fpeforparcod, plpgdes, plpgcondicao, (select count(*) from( select regexp_split_to_table(plpgcondicao, ';')) p) as num_parc, estcustocompra * pviuvemult * pviqtdeatecar as estcustocompra, estcustoreal * pviuvemult * pviqtdeatecar as estcustoreal, pvtipofrete, row_number() over (order by pviseq) as pviseq, (select count(distinct pvplpgpvcod) from pvplpg where pvplpgpvcod = pvcod) as qtparcplpgnegoc, pvvol, (pviqtdeatecar * uvepesobruto) as pvpesobruto, (pviqtdeatecar * uvepesoliq) as pvpesoliq, pvdtentrega, pvvlfrete, pvivlfrete, --Se é consumidor final e orig<>dest case when (parconsfinal = 'S' and gtaliqicms > 0 and (select munufsigla from par join mun on parmuncod = muncod where parcod = pvempparcod) <> (select lpuf from lp where lpcod = f_livro_do_cliente(pvcliparcod, pvempparcod))) then tribdifalpercfcp else 0 end as tribdifalpercfcp, case when (parconsfinal = 'S' and gtaliqicms > 0 and (select munufsigla from par join mun on parmuncod = muncod where parcod = pvempparcod) <> (select lpuf from lp where lpcod = f_livro_do_cliente(pvcliparcod, pvempparcod))) then tribdifalpercicms else 0 end as tribdifalpercicms, case when (parconsfinal = 'S' and gtaliqicms > 0 and (select munufsigla from par join mun on parmuncod = muncod where parcod = pvempparcod) <> (select lpuf from lp where lpcod = f_livro_do_cliente(pvcliparcod, pvempparcod))) then tribdifalpercpart else 0 end as tribdifalpercpart, ----------------------- --Modelo do Doc (01, 55 ,65) (select laymodelo from opnf join eol on eolopnfcod = opnfcod and eolempparcod = pvempparcod join lay on eollaycod = laycod where opnfcod = pvopnfcod) as modelo, pviinfadprod, pvipedcli, opnfusaentregafutura, opnfusaipinoicms, pvmetrocubico, pvimetrocubico, coalesce(cli_perc_fin, 0) as cli_perc_fin, coalesce(cli_tipo_perc_fin, 'P') as cli_tipo_perc_fin, ben_cbenef, opnf_nao_mov_est, coalesce(benefcod, 0) as benefcod, gtbenefredaliqsaida, pvrefnfcod from( select pvipvempparcod, pvipvcod, protipo as tipoproduto, case when protipo = 'KT' then prompprocod else 0 end as kitprocod, case when protipo = 'KT' then prompmpcod else pviprocod end as pviprocod, case when protipo = 'KT' then (select uvecod from uve where uveprocod = prompmpcod and uvetipo = 'P' limit 1) else pviuvecod end as pviuvecod, case when protipo = 'KT' then (select uvedes from uve where uveprocod = prompmpcod and uvetipo = 'P' limit 1) else pviuvedes end as pviuvedes, case when protipo = 'KT' then (select uveun from uve where uveprocod = prompmpcod and uvetipo = 'P' limit 1) else pviuveun end as pviuveun, case when protipo = 'KT' then (select uvemult from uve where uveprocod = prompmpcod and uvetipo = 'P' limit 1) else pviuvemult end as pviuvemult, case when protipo = 'KT' then cast(pviqtde * prompmpqtde as numeric(14, 4)) else pviqtde end as pviqtde, case when protipo = 'KT' then cast(pviqtde * prompmpqtde as numeric(14, 4)) else pviqtdeate end as pviqtdeate, case when protipo = 'KT' then cast(pviqtde * prompmpqtde as numeric(14, 4)) else pviqtdeatecar end as pviqtdeatecar, --Se Produto KIT round(case when protipo = 'KT' then (select fprvlven from f_preco(f_livro_do_cliente(pvcliparcod, pvempparcod), null, null, pvplpgcod, null, cast(prompmpcod as text)) where fprprocod = prompmpcod and fprembcod =(select uvecod from uve where uveprocod = prompmpcod and uvetipo = 'P' limit 1))else pvivltab end, 2) as pvivltab, --Se Produto KIT round(case when protipo = 'KT' then(select fprvlven from f_preco(f_livro_do_cliente(pvcliparcod, pvempparcod), null, null, pvplpgcod, null, cast(prompmpcod as text)) where fprprocod = prompmpcod and fprembcod =(select uvecod from uve where uveprocod = prompmpcod and uvetipo = 'P' limit 1))*(1-(round((pvivltab-pvivlven)/ pvivltab * 100, 2)/ 100)) else pvivlven end, 4) as pvivlven, --Se Produto KIT round(case when protipo = 'KT' then round((select fprvlven from f_preco(f_livro_do_cliente(pvcliparcod, pvempparcod), null, null, pvplpgcod, null, cast(prompmpcod as text)) where fprprocod = prompmpcod and fprembcod =(select uvecod from uve where uveprocod = prompmpcod and uvetipo = 'P' limit 1))*(1-(round((pvivltab-pvivlven)/ pvivltab * 100, 2)/ 100)), 2)*(prompmpqtde * pviqtdeatecar)::numeric else pvivltotal end, 2) as pvivltotal, pviseq, pvibasedebcred, pvivlfrete, pviinfadprod, coalesce (pvipedcli, 0) as pvipedcli, pvimetrocubico from pv join pvi on pvcod = pvipvcod join pro on pviprocod = procod join uve on procod = uveprocod and pviuvecod = uvecod left join promp on pviprocod = prompprocod and protipo = 'KT' ) as i ----------------------- join pv on pvipvcod = pvcod join cli on pvcliparcod = cliparcod join par on cliparcod = parcod join loc on cliloccod = loccod join opnf on pvopnfcod = opnfcod join plpg on pvplpgcod = plpgcod --join pvi on pvcod=pvipvcod and pvempparcod=pvipvempparcod join pro on pviprocod = procod join est on pviprocod = estprocod and pvipvempparcod = estempparcod join uve on uveprocod = pviprocod and uvecod = pviuvecod join emp on pvipvempparcod = empparcod join regtrib on empregtribcod = regtribcod left join benef on empbenefcod = benefcod --trib por benef left join tribbenef on regtribcod = tribbenefregtribcod and tribbenefuforig =(select munufsigla from par join mun on parmuncod = muncod where parcod = pvempparcod) and tribbenefufdest =(select lpuf from lp where lpcod = f_livro_do_cliente(pvcliparcod, pvempparcod)) and tribbenefbenefcod = clibenefcod and tribbenefprocod = procod --trib por produto left join tribpro on regtribcod = tribproregtribcod and tribprouforig =(select munufsigla from par join mun on parmuncod = muncod where parcod = pvempparcod) and tribproufdest =(select lpuf from lp where lpcod = f_livro_do_cliente(pvcliparcod, pvempparcod)) and tribproprocod = procod --trib por ncm left join trib on regtribcod = tribregtribcod and tribuforig =(select munufsigla from par join mun on parmuncod = muncod where parcod = pvempparcod) and tribufdest =(select lpuf from lp where lpcod = f_livro_do_cliente(pvcliparcod, pvempparcod)) and tribncm = proncm -- se utilizar GT de OPNF --left join gt on tribgtcod=gtcod --da prioridade para gt por opnf, depois por trib produto e por fim trib ncm left join gt on gtcod = case when opnfgt = 'S' and coalesce(tribbenefuforig, tribprouforig, tribuforig)= coalesce(tribbenefufdest, tribproufdest, tribufdest) then opnfgtcode when opnfgt = 'S' and coalesce(tribbenefuforig, tribprouforig, tribuforig)<> coalesce(tribbenefufdest, tribproufdest, tribufdest) then opnfgtcodi else coalesce(tribbenefgtcod, tribprogtcod, tribgtcod) end left join beneficios on ben_id = gt_ben_id --verificar PIS/COFINS left join cstpiscofins on regtribcod = cstpiscofins_regtribcod and estcstpiscofinscod = cstpiscofins_cod --REGRA DIFAL left join tribdifal on tribdifaluf =(select lpuf from lp where lpcod = f_livro_do_cliente(pvcliparcod, pvempparcod)) --where pviqtdeatecar>0 and pvipvempparcod=1 and pvipvcod=46984 where pviqtdeatecar>0 and pvipvempparcod = p_empresa and pvipvcod = p_pedido loop if not v_inseriuCab then --Verifica se cab nf já foi inserido --************************************************************* --INSERIR CAB NF --************************************************************* --OBTER OBS NF select trim(confobsnf) into v_confobsnf from conf where confempparcod = p_empresa; select coalesce(conf_usa_desconta_st_do_preco,'N') into v_DescontaStdoPreco from conf where confempparcod = p_empresa; select case when conffatdsaid = 'S' then coalesce(p_horariosaida, now()) else now() end into v_datahorasaida from conf where confempparcod = p_empresa; execute coalesce(v_confobsnf, 'select null') into v_obsnf using p_pedido; select nextval('nf_nfcod_seq') into v_nfcod; --OBTER PROX CODIGO/SEQ DE NF - CAMPO CHAVE --INSERT NF insert into nf (nfcadusuparcod, nfcadhorario, nfaltusuparcod, nfalthorario, nfcod, nfempparcod, nfparcod, nfnum, nfserie, nfsta, nfdtemi, nfdtsai, nfhrsai, nfopnfcod, nfespecie, nftipoemissao, nfmodelo, nfvl, nfvlpro, nftipofrete, nfpesobruto, nfpesoliq, nfvol, nfnumvol, nfobs, nfpvcod, nfplpgcod, nftccod, nfrcaparcod, nfsupparcod, nfrcaauxparcod, nfcarcod, nfcarcodorig, nfordcar, nftranspcod, nfveicod, nfmotparcod, nfconhecfretecod, nfpccod, nfdevolnum, nfdevolserie, nfmotivdevolnfcod, nfmetrocubico, nfrefnfcod, nfibsvlmun, nfibsvluf, nfcbsvl ) values ( p_usuario,--nfcadusuparcod v_agora,--nfcadhorario null,--nfaltusuparcod null,--nfalthorario v_nfcod,--nfcod rec_pv.pvempparcod, rec_pv.pvcliparcod, v_nfcod,--update - Recebe v_nfcod/seq provisoriamente ate gravar nfi, cpr e cprpg '0',-- update - Recebe 0 provisoriamente ate gravar nfi, cpr e cprpg 'FT',--nfsta cast(p_dtemissao as date),--nfdtemi cast(v_datahorasaida as date),--nfdtsai cast(v_datahorasaida as time),--nfhrsai rec_pv.pvopnfcod, rec_pv.opnfesp,--nfopnfesp character(4) rec_pv.opnftipoemissaonf,--nftipoemissao rec_pv.modelo,--nfmodelo 0,--nfvl update - Recebe 0 provisoriamente ate gravar nfi 0,--nfvlpro update - Recebe 0 provisoriamente ate gravar nfi rec_pv.pvtipofrete,--nftipofrete coalesce(rec_pv.pvpesobruto, 0),--nfpesobruto update - Recebe 0 provisoriamente ate gravar nfi coalesce(rec_pv.pvpesoliq, 0),--nfpesoliq update - Recebe 0 provisoriamente ate gravar nfi coalesce(rec_pv.pvvol, 0),--nfvol 0,--nfnumvol update - Recebe 0 provisoriamente ate gravar nfi v_obsnf,--nfobs rec_pv.pvcod,--nfpvcod rec_pv.pvplpgcod,--nfplpgcod rec_pv.pvtccod, rec_pv.pvrcaparcod,--nfrcaparcod rec_pv.pvsupparcod,--nfsupparcod rec_pv.pvrcaauxparcod,--nfrcaauxparcod rec_pv.pvcarcod,--nfcarcod null,--nfcarcodorig null,--nfordcar rec_pv.transpcod,--nftranspcod p_veiculo,--nfveicod p_motorista,--nfmotparcod null,--nfconhecfretecod null,--nfpccod null,--nfdevolnum null,--nfdevolserie null,--nfmotivdevolnfcod rec_pv.pvmetrocubico,--nfmetrocubico rec_pv.pvrefnfcod, 0, --nfibsvlmun, update - Recebe 0 provisoriamente ate gravar nfi 0, --nfibsvluf, update - Recebe 0 provisoriamente ate gravar nfi 0 --nfcbsvl update - Recebe 0 provisoriamente ate gravar nfi ); --INSERIR REGISTRO EM NFE insert into nfe(nfecadusuparcod, nfecadhorario, nfealtusuparcod, nfealthorario, nfenfempparcod, nfenfparcod, nfenfnum, nfenfserie, nfenfcod ) values ( p_usuario,--nfecadusuparcod integer, v_agora,--nfecadhorario timestamp without time zone, null,--nfealtusuparcod integer, null,--nfealthorario timestamp without time zone, rec_pv.pvempparcod,--nfenfempparcod integer NOT NULL, rec_pv.pvcliparcod,--nfenfparcod integer NOT NULL, v_nfcod,--nfenfnum integer NOT NULL, update - Recebe v_nfcod/seq provisoriamente ate gravar nfi, cpr e cprpg '0',--nfenfserie character varying(4) NOT NULL, update - Recebe 0 provisoriamente ate gravar nfi, cpr e cprpg v_nfcod--nfenfcod integer NOT NULL, ); --INSERIR REGISTRO EM NFECF insert into nfecf (nfecfcadusuparcod, nfecfcadhorario, nfecfaltusuparcod, nfecfalthorario, nfecfnfempparcod, nfecfnfparcod, nfecfnfnum, nfecfnfserie, nfecfnfcod ) values ( p_usuario,--nfecfcadusuparcod integer, v_agora,--nfecfcadhorario timestamp without time zone, null,--nfecfaltusuparcod integer, null,--nfecfalthorario timestamp without time zone, rec_pv.pvempparcod,--nfecfnfempparcod integer NOT NULL, rec_pv.pvcliparcod,--nfecfnfparcod integer NOT NULL, v_nfcod,--nfecfnfnum integer NOT NULL, update - Recebe v_nfcod/seq provisoriamente ate gravar nfi, cpr e cprpg '0',--nfecfnfserie character varying(4) NOT NULL, update - Recebe 0 provisoriamente ate gravar nfi, cpr e cprpg v_nfcod--nfecfnfcod integer NOT NULL, ); v_inseriuCab := true; end if; --IF NOT inseriuCab THEN --************************************************************* --INSERIR ITEM - NFI --************************************************************* --ICMS NORMAL v_visento := 0; v_vbasecalc := 0; v_vicms := 0; v_voutros := 0; v_vipi := 0; v_vbasecalc_efet := 0; v_vicms_efet := 0; v_vpro := 0; v_vproFinal := 0; v_vpro := rec_pv.pvivltotal; v_vproFinal := rec_pv.pvivltotal; if rec_pv.isento = 'S' then v_visento := v_vpro; else --Obter base de calculo if rec_pv.pauta > 0 then v_vbasecalc := rec_pv.pviqtdeatecar * rec_pv.pauta; else if rec_pv.percrbcicms > 0 then v_vbasecalc := (v_vpro - round(v_vpro * rec_pv.percrbcicms / 100, 2)); else --Compor base de calculo se aliq icms > 0 if rec_pv.aliqicms > 0 then v_vbasecalc := v_vpro; else v_vbasecalc := 0; end if; end if; end if; -- VBaseCalc recebe despesa de boleto no primeiro item caso configurado no cliente v_vbasecalc := coalesce(v_vbasecalc, 0) + case when v_vbasecalc>0 then coalesce(rec_pv.despbol, 0) else 0 end; v_vicms := round(v_vbasecalc * coalesce(rec_pv.aliqicms, 0)/ 100, 2); v_voutros := rec_pv.pvivltotal-v_vbasecalc; v_vbasecalc_efet := coalesce(v_vbasecalc, 0) + case when v_vbasecalc>0 then coalesce(rec_pv.despbol, 0) else 0 end; if coalesce(rec_pv.gtbenefredaliqsaida, 0)>0 then v_vicms_efet := round(v_vicms-(v_vicms * rec_pv.gtbenefredaliqsaida / 100), 2); else v_vicms_efet := round(v_vbasecalc * coalesce(rec_pv.aliqicmsefet, 0)/ 100, 2); end if; if rec_pv.opnfusaipinoicms = 'S' then v_vipi := round(rec_pv.pvivltotal * coalesce(rec_pv.percipi, 0)/ 100, 2); v_vbasecalc := coalesce(v_vbasecalc, 0) + case when v_vbasecalc>0 then coalesce(v_vipi, 0) else 0 end; v_vicms := round(v_vbasecalc * coalesce(rec_pv.aliqicms, 0)/ 100, 2); v_voutros := case when v_vpro-v_vbasecalc < 0 then 0 else rec_pv.pvivltotal - v_vbasecalc end; v_vbasecalc_efet := coalesce(v_vbasecalc, 0) + case when v_vbasecalc>0 then coalesce(v_vipi, 0) else 0 end; if coalesce(rec_pv.gtbenefredaliqsaida, 0)>0 then v_vicms_efet := round(v_vicms-(v_vicms * rec_pv.gtbenefredaliqsaida / 100), 2); else v_vicms_efet := round(v_vbasecalc * coalesce(rec_pv.aliqicmsefet, 0)/ 100, 2); end if; end if; end if; --SUBSTITUICAO v_vbasecalcST := 0; v_vlicmsST := 0; v_vbcfcp := 0; v_vbcfcpST := 0; v_vlfcpST := 0; v_vlfcp := 0; if rec_pv.opnfsta in ('GC', 'C') then v_vipi := round(rec_pv.pvivltotal * coalesce(rec_pv.percipi, 0)/ 100, 2); if rec_pv.aliqicmsret > 0 then if v_DescontaStdoPreco = 'N' then if rec_pv.pautaret > 0 then v_vbasecalcST := rec_pv.pviqtdeatecar * rec_pv.pautaret; else if rec_pv.percrbcicmsret > 0 then --v_vbasecalcST := round((rec_pv.pvivltotal+v_vipi+frete)*rec_pv.percrbcicmsret/100,4); v_vbasecalcST := (v_vpro - round((v_vpro + v_vipi)* rec_pv.percrbcicmsret / 100, 2)); else --v_vbasecalcST := rec_pv.pvivltotal+v_vipi+frete; v_vbasecalcST := v_vpro + v_vipi; end if; end if; v_vbasecalcST := round((v_vbasecalcST + (case when v_vbasecalcST>0 then coalesce(rec_pv.despbol, 0) else 0 end))*(1 +(coalesce(rec_pv.aliqiva, 0)/ 100)), 2); v_vlicmsST := round((v_vbasecalcST * rec_pv.aliqicmsret / 100)-coalesce(v_vicms, 0), 2); else --v_DescontaStdoPreco = 'S' if rec_pv.pautaret > 0 then v_vbasecalcST := rec_pv.pviqtdeatecar * rec_pv.pautaret; else if rec_pv.percrbcicmsret > 0 then v_vbasecalcST := (v_vpro - round((v_vpro + v_vipi)* rec_pv.percrbcicmsret / 100, 6)); else --= (R$1.050,00 * 100%) / 114,42% = R$ 917,67 -- select round(((1 + (66.65+0) / 100) * 20) - 20,4) -- select 100+9 -- select round(((15.65 * 100)) / 113.33 ,6) v_indice_st := round(((1 + (coalesce(rec_pv.aliqiva, 0)+coalesce(rec_pv.fcpaliqicmsst, 0)) / 100) * rec_pv.aliqicmsret) - rec_pv.aliqicms,6); v_indice_st := 100+v_indice_st; v_vpro := round((v_vpro * 100) / v_indice_st,6); --NECESSARIO RECALCULAR O ICMS if rec_pv.pauta > 0 then v_vbasecalc := rec_pv.pviqtdeatecar * rec_pv.pauta; else if rec_pv.percrbcicms > 0 then v_vbasecalc := (v_vpro - round(v_vpro * rec_pv.percrbcicms / 100, 2)); else --Compor base de calculo se aliq icms > 0 if rec_pv.aliqicms > 0 then v_vbasecalc := v_vpro; else v_vbasecalc := 0; end if; end if; end if; v_vbasecalc := coalesce(v_vbasecalc, 0) + case when v_vbasecalc>0 then coalesce(v_vipi, 0) else 0 end; v_vicms := round(v_vbasecalc * coalesce(rec_pv.aliqicms, 0)/ 100, 2); v_voutros := case when rec_pv.pvivltotal-v_vbasecalc < 0 then 0 else rec_pv.pvivltotal-v_vbasecalc end; v_vbasecalc_efet := coalesce(v_vbasecalc, 0) + case when v_vbasecalc>0 then coalesce(v_vipi, 0) else 0 end; v_vicms_efet := round(v_vbasecalc * coalesce(rec_pv.aliqicmsefet, 0)/ 100, 2); v_vbasecalcST := v_vpro + v_vipi; v_vbasecalcST := round((v_vbasecalcST + (case when v_vbasecalcST>0 then coalesce(rec_pv.despbol, 0) else 0 end))*(1 +(coalesce(rec_pv.aliqiva, 0)/ 100)), 6); v_vlicmsST := round((v_vbasecalcST * rec_pv.aliqicmsret / 100)-coalesce(v_vicms, 0), 6); end if; end if; end if; end if; if rec_pv.fcpaliqicms > 0 then v_vbcfcp := v_vbasecalc;--rec_pv.pvivltotal; v_vlfcp := round((v_vbcfcp * rec_pv.fcpaliqicms / 100), 2); end if; IF (rec_pv.fcpaliqicmsst > 0) and (v_vbasecalcST > 0) then v_vbcfcpST := v_vbasecalcST; v_vlfcpST := round((v_vbcfcpST*rec_pv.fcpaliqicmsst/100),2); v_vlfcpST := round(v_vlfcpST-v_vlfcp,2); end if; --corrige o valor final baseado na forma de calculo if v_DescontaStdoPreco = 'N' then v_vproFinal := v_vpro; else --v_DescontaStdoPreco = 'S' v_vproFinal := v_vproFinal - v_vlicmsST - v_vlfcpST; v_vbasecalc := coalesce(v_vproFinal, 0) + case when v_vproFinal>0 then coalesce(rec_pv.despbol, 0) else 0 end; v_vicms := round(v_vbasecalc * coalesce(rec_pv.aliqicms, 0)/ 100, 2); v_voutros := rec_pv.pvivltotal-v_vbasecalc; v_vbasecalc_efet := coalesce(v_vbasecalc, 0) + case when v_vbasecalc>0 then coalesce(rec_pv.despbol, 0) else 0 end; end if; end if; --IPI/ST - QD PEDIDO POSSUI INDICE (TENDO COMO BASE O BLOCO ANTERIOR) if rec_pv.opnfsta in ('G') and rec_pv.pvindice > 0 then v_vipi := round(v_vpro * coalesce(rec_pv.percipi, 0)/ 100, 2); -- Linha específica para esse bloco v_vipi := round(v_vipi *(rec_pv.pvindice / 100.0), 2); if rec_pv.aliqicmsret > 0 then if rec_pv.pautaret > 0 then v_vbasecalcST := rec_pv.pviqtdeatecar * rec_pv.pautaret; else if rec_pv.percrbcicmsret > 0 then --v_vbasecalcST := round((rec_pv.pvivltotal+v_vipi+frete)*rec_pv.percrbcicmsret/100,4); v_vbasecalcST := round((v_vpro + v_vipi)* rec_pv.percrbcicmsret / 100, 4); else --v_vbasecalcST := rec_pv.pvivltotal+v_vipi+frete; v_vbasecalcST := v_vpro + v_vipi; end if; end if; v_vbasecalcST := round(v_vbasecalcST *(1 +(coalesce(rec_pv.aliqiva, 0)/ 100)), 6); v_vlicmsST := round((v_vbasecalcST * rec_pv.aliqicmsret / 100)-coalesce(v_vicms, 0), 6); -- Linhas específicas para esse bloco v_vbasecalcST := round((v_vbasecalcST + (case when v_vbasecalcST>0 then coalesce(rec_pv.despbol, 0) else 0 end))*(rec_pv.pvindice / 100.0), 6); v_vlicmsST := round(v_vlicmsST *(rec_pv.pvindice / 100.0), 6); end if; if rec_pv.opnfusaipinoicms = 'S' then v_vbasecalc := coalesce(v_vbasecalc, 0) + case when v_vbasecalc>0 then coalesce(v_vipi, 0) else 0 end; v_vicms := round(v_vbasecalc * coalesce(rec_pv.aliqicms, 0)/ 100, 2); v_voutros := case when v_vpro-v_vbasecalc < 0 then 0 else rec_pv.pvivltotal - v_vbasecalc end; v_vbasecalc_efet := coalesce(v_vbasecalc, 0) + case when v_vbasecalc>0 then coalesce(v_vipi, 0) else 0 end; v_vicms_efet := round(v_vbasecalc * coalesce(rec_pv.aliqicmsefet, 0)/ 100, 2); end if; end if; -- por enquanto usamos a base gerada pelo ICMS -- Base de cálculo IBS/CBS --(+) vProd --(+) vServ --(+) vFrete --(+) vSeg --(+) vOutro --(+) vII --(-) vDesc --(-) vPIS --(-) vCOFINS --(-) vICMS --(-) vICMSUFDest --(-) vFCP --(-) vFCPUFDest --(-) vICMSMono --(-) vISSQN --(+) vIS v_BaseCalcIbsCbs := 0; IF rec_pv.gtcbsaliq > 0 THEN v_BaseCalcIbsCbs := v_vproFinal + COALESCE(rec_pv.pvivlfrete, 0) + COALESCE(v_voutros, 0) - COALESCE(v_vdesc, 0) - COALESCE(round(rec_pv.bcpis * rec_pv.pisaliq / 100, 2), 0) - COALESCE(round(rec_pv.bccofins * rec_pv.cofinsaliq / 100, 2), 0) - COALESCE(v_vicms, 0) - COALESCE(v_vlfcp, 0); END IF; -- IBS MUN (com crédito presumido) v_ibsmun := 0; if rec_pv.gtibsaliqmun > 0 then v_ibsmun_bruto := round(v_BaseCalcIbsCbs * coalesce(rec_pv.gtibsaliqmun, 0)/ 100, 2); v_ibsmun := round(v_ibsmun_bruto * (1 - coalesce(rec_pv.gtibspercredmun, 0)/100), 2); end if; -- IBS UF (com crédito presumido) v_ibsuf := 0; if rec_pv.gtibsaliquf > 0 then v_ibsuf_bruto := round(v_BaseCalcIbsCbs * coalesce(rec_pv.gtibsaliquf, 0)/ 100, 2); v_ibsuf := round(v_ibsuf_bruto * (1 - coalesce(rec_pv.gtibspercreduf, 0)/100), 2); end if; -- CBS (com crédito presumido) v_cbs := 0; if rec_pv.gtcbsaliq > 0 then v_cbs_bruto := round(v_BaseCalcIbsCbs * coalesce(rec_pv.gtcbsaliq, 0)/ 100, 2); v_cbs := round(v_cbs_bruto * (1 - coalesce(rec_pv.gtcbspercred, 0)/100), 2); end if; insert into nfi (nficadusuparcod, nficadhorario, nfialtusuparcod, nfialthorario, nfinfempparcod, nfinfparcod, nfinfnum, nfinfserie, nfinfcod, nfiprocod, nfiuvecod, nfiuvedes, nfiuveun, nfiuvemult, nfiqtde, nfivltabunit, nfivlunit, nfivl, nficfopcod, nficstcod, nficsosncod, nfialiqcredsn, nfivlcredicmssn, nfibcicms, nfipercredbcicms, nfialiqicms, nfialiqicmsefet, nfivlicms, nfibcicmsst, nfipercredbcicmsst, nfialiqicmsst, nfivlicmsst, nfibcipi, nficstipicod, nfialiqipi, nfivlipi, nficstpiscofinscod, nfialiqpis, nfivlpautapis, nfivlpis, nfialiqcofins, nfivlpautacofins, nfivlcofins, nfivlfrete, nfivlseguro, nfivldesc, nfivloutrasdesp, nfivlisento, nfivloutros, nfivldesprat, nfivldespnrat, nficustocompra, nficustoreal, nfivlvensug, nfiforparcod, nfibcpis, nfibccofins, nfibcqtpis, nfibcqtcofins, nfipuvecod, nfipuvedes, nfipuveun, nfipuvemult, nfipqtde, nfipvltabunit, nfipvlunit, nfiuvenf, nfiseq, nfibasedebcred, nfiqtdefalta, nfiqtdecorte, --difal nfidifalbcfcpdest, nfidifalpercfcpdest, nfidifalpercicmsdest, nfidifalpercpartdest, nfidifalvlfcpdest, nfidifalvlicmsdest, nfidifalvlicms, nfiinfadprod, --FCP nfibcfcp, nfifcpaliqicms, nfifcpvlqicms, nfibcfcpst, nfifcpaliqicmsst, nfifcpvlqicmsst, nfialiqiva, nfibcicmsefet, nfivlicmsefet, nfipedcli, nfimetrocubico, nficbenef, --classificacao fiscal nficlasstribcod, --IBS Mun nfiibsaliqmun, nfiibspercredmun, nfiibsbcmun, nfiibsvlmun, --IBS UF nfiibsaliquf, nfiibspercreduf, nfiibsbcuf, nfiibsvluf, --CBS nficbsaliq, nficbspercred, nficbsbc, nficbsvl ) values ( p_usuario,--nficadusuparcod v_agora,--nficadhorario, null,--nfialtusuparcod, null,--nfialthorario, rec_pv.pvempparcod,--nfinfempparcod, rec_pv.pvcliparcod,--nfinfparcod, v_nfcod,--nfinfnum, Receber v_nfcod/seq provisoriamente ate gravar nfi, cpr e cprpg '0',--nfinfserie, Receber v_nfcod/seq provisoriamente ate gravar nfi, cpr e cprpg v_nfcod,--nfinfcod, rec_pv.pviprocod,--nfiprocod, rec_pv.pviuvecod,--nfiuvecod, rec_pv.pviuvedes,--nfiuvedes, rec_pv.pviuveun,--nfiuveun, rec_pv.pviuvemult,--nfiuvemult, rec_pv.pviqtdeatecar,--nfiqtde, rec_pv.pvivltab,--nfivltabunit, v_vproFinal/rec_pv.pviqtdeatecar,-- rec_pv.pvivlven,--nfivlunit v_vproFinal,--rec_pv.pvivltotal,--nfivl, rec_pv.cfopcod,--nficfopcod, rec_pv.cst,--nficstcod, rec_pv.gtcsosncod,--nficsosncod, rec_pv.gtpCredSN,--nfialiqcredsn, rec_pv.vCredICMSSN,--nfivlcredicmssn, v_vbasecalc,--nfibcicms, rec_pv.percrbcicms,--nfipercredbcicms, rec_pv.aliqicms,--nfialiqicms, rec_pv.aliqicmsefet,--nfialiqicmsefet v_vicms,--nfivlicms, v_vbasecalcST,--nfibcicmsst, rec_pv.percrbcicmsret,--nfipercredbcicmsst, coalesce(rec_pv.aliqicmsret, 0),--(coalesce(rec_pv.aliqicmsret,0)+coalesce(rec_pv.fcpaliqicmsst,0)),--nfialiqicmsst, v_vlicmsST,--nfivlicmsst, rec_pv.pvivltotal,--nfibcipi rec_pv.cstipi,--nficstipicod, rec_pv.percipi,--nfialiqipi, v_vipi,--nfivlipi, rec_pv.piscst,--nficstpiscofinscod, rec_pv.pisaliq,--nfialiqpis, rec_pv.pisvlpauta,--nfivlpautapis, round(rec_pv.bcpis * rec_pv.pisaliq / 100, 2),--nfivlpis, rec_pv.cofinsaliq,--nfialiqcofins, null,--nfivlpautacofins, round(rec_pv.bccofins * rec_pv.cofinsaliq / 100, 2),--nfivlcofins, rec_pv.pvivlfrete,--nfivlfrete, null,--nfivlseguro, 0,--rec_pv.vldesc,--nfivldesc, rec_pv.despbol,--nfivloutrasdesp, v_visento,--nfivlisento, v_voutros,--nfivloutros, null,--nfivldesprat, null,--nfivldespnrat, rec_pv.estcustocompra,--nficustocompra, rec_pv.estcustoreal,--nficustoreal, null,--nfivlvensug, rec_pv.fpeforparcod,--nfiforparcod, rec_pv.bcpis,--nfibcpis numeric(14,4), rec_pv.bccofins,--nfibccofins numeric(14,4), rec_pv.bcqtpis,--nfibcqtpis numeric(14,4), rec_pv.bcqtcofins,--nfibcqtcofins numeric(14,4), rec_pv.puvecod,--nfipuvecod integer, rec_pv.puvedes,--nfipuvedes character varying(60), rec_pv.puveun,--nfipuveun character varying(10), rec_pv.puvemult,--nfipuvemult numeric(14,4), rec_pv.pqtde,--nfipqtde numeric(14,4) DEFAULT 0, rec_pv.pvltabunit,--nfipvltabunit numeric(14,4) DEFAULT 0, rec_pv.pvlven,--nfipvlunit numeric(14,4) DEFAULT 0, rec_pv.uvenf,--nfiuvenf char(1) DEFAULT 'V' rec_pv.pviseq,--nfiseq rec_pv.pvibasedebcred,--pvibasedebcred rec_pv.qtdefalta,--nfiqtdefalta rec_pv.qtdecorte,--nfiqtdecorte case when rec_pv.tribdifalpercicms>0 then v_vbasecalc else 0 end,--nfidifalbcfcpdest, rec_pv.tribdifalpercfcp,--nfidifalpercfcpdest, rec_pv.tribdifalpercicms,--nfidifalpercicmsdest, rec_pv.tribdifalpercpart,--nfidifalpercpartdest, round(rec_pv.tribdifalpercfcp * v_vbasecalc / 100, 2),-- nfidifalvlfcpdest, --Formula = round(((pICMSUFDest-pICMSInter)*vBCUFDest/100)*pICMSInterPart/100,2) case when rec_pv.tribdifalpercicms>0 then round(((rec_pv.tribdifalpercicms)* v_vbasecalc / 100)* rec_pv.tribdifalpercpart / 100, 2) else 0 end,--nfidifalvlicmsdest, --Formula = round(((pICMSUFDest-pICMSInter)*vBCUFDest/100)*([100]-pICMSInterPart)/100,2) [100]=>menos 100 pois se tribdifalpart=40% então origem paga o resto case when rec_pv.tribdifalpercicms>0 then round(((rec_pv.tribdifalpercicms)* v_vbasecalc / 100)*(100-rec_pv.tribdifalpercpart)/ 100, 2) else 0 end,--nfidifalvlicms rec_pv.pviinfadprod, v_vbcfcp,--nfibcfcp rec_pv.fcpaliqicms, v_vlfcp, v_vbcfcpST,--nfibcfcpst rec_pv.fcpaliqicmsst, v_vlfcpST,--nfifcpvlqicmsst, rec_pv.aliqiva, v_vbasecalc_efet,--nfibcicmsefet, v_vicms_efet,--nfivlicmsefet rec_pv.pvipedcli,--nfipedcli rec_pv.pvimetrocubico, rec_pv.ben_cbenef,--nficbenef rec_pv.gtclasstribcod, -- nficlasstribcod, rec_pv.gtibsaliqmun, -- nfiibsaliqmun, rec_pv.gtibspercredmun, -- nfiibspercredmun, v_BaseCalcIbsCbs, -- nfiibsbcmun, v_ibsmun, -- nfiibsvlmun, rec_pv.gtibsaliquf, -- nfiibsaliquf, rec_pv.gtibspercreduf, -- nfiibspercreduf, v_BaseCalcIbsCbs, -- nfiibsbcuf, v_ibsuf, -- nfiibsvluf, rec_pv.gtcbsaliq, -- nficbsaliq, rec_pv.gtcbspercred, -- nficbspercred, v_BaseCalcIbsCbs, -- nficbsbc, v_cbs -- nficbsvl, ); end loop; --************************************************************* --UPDATE PESO --************************************************************* update nf set nfpesobruto = t.t_pesobruto, nfpesoliq = t.t_pesoliq from( select case when coalesce(sum(uvepesobruto), 0) > 0 then sum((pviqtdeatecar * uvepesobruto)) else 0 end as t_pesobruto, case when coalesce(sum(uvepesoliq), 0) > 0 then sum((pviqtdeatecar * uvepesoliq)) else 0 end as t_pesoliq from pvi join uve on pviprocod = uveprocod and pviuvecod = uvecod where pviqtdeatecar>0 and pvipvempparcod = p_empresa and pvipvcod = p_pedido ) as t where nfcod = v_nfcod; --************************************************************* --UPDATE NF PARA DISPONIBILIZAR VL TOTAL PARA GERAR CPR --************************************************************* update nf set nfvl = i.nfvl,--nfvl numeric(14,4) DEFAULT 0, nfvlpro = i.nfvlpro,--nfvlpro numeric(14,4) DEFAULT 0, nfbcicms = i.nfbcicms,--nfbcicms numeric(14,4) DEFAULT 0, nfvlicms = i.nfvlicms,--nfvlicms numeric(14,4) DEFAULT 0, nfbcicmsst = i.nfbcicmsst,--nfbcicmsst numeric(14,4) DEFAULT 0, nfvlicmsst = i.nfvlicmsst,--nfvlicmsst numeric(14,4) DEFAULT 0, nfvlfrete = i.nfvlfrete,--nfvlfrete numeric(14,4) DEFAULT 0, nfvlseguro = i.nfvlseguro,--nfvlseguro numeric(14,4) DEFAULT 0, nfvldesc = 0,--nfvldesc=i.nfvldesc,--nfvldesc numeric(14,4) DEFAULT 0, nfvloutrasdesp = i.nfvloutrasdesp,--nfvloutrasdesp numeric(14,4) DEFAULT 0, nfvlipi = i.nfvlipi,--nfvlipi numeric(14,4) DEFAULT 0, nfvlisento = i.nfvlisento,--nfvlisento numeric(14,4) DEFAULT 0, nfvloutros = i.nfvloutros,--nfvloutros numeric(14,4) DEFAULT 0, nfnumvol = i.nfnumvol, --nfnumvol numeric(14,4), nfibsvlmun = i.nfibsvlmun, nfibsvluf = i.nfibsvluf, nfcbsvl = i.nfcbsvl from( select nfinfcod, count(nfiprocod) as qtitens, sum(coalesce(nfivl, 0))+ sum(coalesce(nfivlipi, 0))+ sum(coalesce(nfivlfrete, 0))+ sum(coalesce(nfivlseguro, 0))+ sum(coalesce(nfivloutrasdesp, 0))+ sum(coalesce(nfivlicmsst, 0))+ sum(coalesce(nfifcpvlqicmsst, 0)) --sum(coalesce(nfivldesc,0)) desconto ja vem do item as nfvl, sum(coalesce(nfibcicms, 0)) as nfbcicms, sum(coalesce(nfivlicms, 0)) as nfvlicms, sum(coalesce(nfibcicmsst, 0)) as nfbcicmsst, sum(coalesce(nfivlicmsst, 0)) as nfvlicmsst, sum(coalesce(nfivl, 0)) as nfvlpro, sum(coalesce(nfivlfrete, 0)) as nfvlfrete, sum(coalesce(nfivlseguro, 0)) as nfvlseguro, sum(coalesce(nfivloutrasdesp, 0)) as nfvloutrasdesp, sum(coalesce(nfivlipi, 0)) as nfvlipi, sum(coalesce(nfivlisento, 0)) as nfvlisento, sum(coalesce(nfivloutros, 0)) as nfvloutros, sum(coalesce(nfivldesc, 0)) as nfvldesc, sum(coalesce(nfiqtde, 0)) as nfnumvol, sum(coalesce(nfiibsvlmun, 0)) as nfibsvlmun, sum(coalesce(nfiibsvluf, 0)) as nfibsvluf, sum(coalesce(nficbsvl, 0)) as nfcbsvl --difal (gravando só nos itens) --nfdifalvlfcpdest, --nfdifalvlicmsdest, --nfdifalvlicms from nfi where nfinfcod = v_nfcod group by nfinfcod ) as i where nfcod = nfinfcod; if rec_pv.opnfcpr = 'S' then --************************************************************* --OBTER PROX CODIGO/SEQ DE CPR - CAMPO CHAVE --************************************************************* select nextval('seq_cpr' || rec_pv.pvempparcod::text) into v_cprcod; --select nfvl-(nfvl*rec_pv.cli_perc_fin/100) into v_vnf from nf where nfcod=v_nfcod; select nfvl into v_vnf from nf where nfcod = v_nfcod; select(nfvl * rec_pv.cli_perc_fin / 100) into v_vdesc from nf where nfcod = v_nfcod; select coalesce(conf_div_st_parcelas, 'N') into v_DivSt from conf where confempparcod = p_empresa; --INSERIR CAB insert into cpr(cprempparcod,-- integer NOT NULL, cprcod,-- integer NOT NULL, cprtipo,-- character(3), cprccpcgcccod,-- integer, cprccpcgpcgcod,-- integer, cprmodg,-- character(2), cprparcod,-- integer, cprdocnum,-- integer, cprdocserie,-- character varying(10), cprprev,-- character(1), cprdemi,-- timestamp with time zone, cprdlan,-- timestamp with time zone, cprvt,-- numeric(14,4) DEFAULT 0, cprvtpg,-- numeric(14,4) DEFAULT 0, cprfunparcod,-- integer, cprpcgcod,-- integer, cprnat,-- character(1), cprrcaparcod,-- integer, cprdevparcod,-- integer, cprobs,-- character varying(250), cpr_cart_codigo,-- integer, cpr_d_competencia,-- date, cpr_ccc_id,-- integer, cpr_conta_id,-- integer, cpr_cc_id,-- integer, cpr_notafiscal,-- character varying(20), cprnfcod-- integer, ) select nfempparcod,--cprempparcod integer NOT NULL, v_cprcod,--cprcod integer NOT NULL, 'CRC',--cprtipo character(3), null,--cprccpcgcccod integer, null,--cprccpcgpcgcod integer, 'FT',--cprmodg character(2), nfparcod,--cprparcod integer, null,--update cprdocnum integer, null,--update cprdocserie character varying(10), 'N',--cprprev character(1), nfdtemi,--cprdemi timestamp with time zone, v_agora,--cprdlan timestamp with time zone, v_vnf,--cprvt numeric(14,4) DEFAULT 0, 0,--cprvtpg numeric(14,4) DEFAULT 0, p_usuario,--cprfunparcod integer, null,--cprpcgcod integer, null,--cprnat character(1), nfrcaparcod,--cprrcaparcod integer, nfparcod,--cprdevparcod integer, 'Referente a saida de Mercadoria',--cprobs character varying(250), 1,--cpr_cart_codigo integer, DATE(v_agora),--cpr_d_competencia date, null,--cpr_ccc_id integer, rec_pv.opnf_conta_id,--cpr_conta_id integer, rec_pv.opnf_cc_id,--cpr_cc_id integer, null,--update cpr_notafiscal character varying(20), v_nfcod--cprnfcod integer; from nf where nfcod = v_nfcod; /* SE PEDIDO COM PLANO NEGOCIADO ENTAO GERAR CPRPG A PARTIR DO PVPLPG SENAO NFPLPGCOD */ ------------------------------------------------------------------------------ --confusadtentregaparagerarfin if coalesce(rec_pv.qtparcplpgnegoc, 0)>0 then --INSERIR CPRPG A PARTIR DE PVPLPG (PLANO NEGOCIADO) insert into cprpg (cprpgcprempparcod,-- integer NOT NULL, cprpgcprcod,-- integer NOT NULL, cprpgcod,-- integer NOT NULL, cprpgdvenc,-- date, cprpgv,-- numeric(14,4), cprpgtccod,-- integer, cprpgsta,-- character(1), cprpgfunparcod,-- integer, cprpgdvenco,-- date, cprpgtccodo,-- integer, cprpg_d_lanc,-- timestamp without time zone, cprpg_d_competencia,-- date, cprpgparc-- varchar(250) ) select cprempparcod,--cprpgcprempparcod integer NOT NULL, v_cprcod,--cprpgcprcod integer NOT NULL, pvplpgparc,--cprpgcod integer NOT NULL, case when coalesce(confusadtentregaparagerarfin, 'N')= 'S' and pvdtentrega is not null then pvplpgdtvenc +(DATE(pvdtentrega)-DATE(now())) else pvplpgdtvenc end as pvplpgdtvenc,--cprpgdvenc date, pvplpgv,--cprpgv numeric(14,4), pvplpgtccod,--cprpgtccod integer, 'A',--cprpgsta character(1), cprfunparcod,--cprpgfunparcod integer, pvplpgdtvenc,--cprpgdvenco date, pvplpgtccod,--cprpgtccodo integer, v_agora,--cprpg_d_lanc timestamp without time zone, cast(v_agora as date),--cprpg_d_competencia date, pvplpgparc--cprpgparc varchar(250) from pvplpg join pv on pvcod = pvplpgpvcod and pvcod = rec_pv.pvcod join cpr on cprempparcod = p_empresa and cprcod = v_cprcod join conf on pvempparcod = confempparcod; else --INSERIR CPRPG A PARTIR DE PLPG insert into cprpg ( cprpgcprempparcod,-- integer NOT NULL, cprpgcprcod,-- integer NOT NULL, cprpgcod,-- integer NOT NULL, cprpgdvenc,-- date, cprpgv,-- numeric(14,4), --Gerar conta com vl total nf menos ST cprpgtccod,-- integer, cprpgsta,-- character(1), cprpgfunparcod,-- integer, cprpgdvenco,-- date, cprpgtccodo,-- integer, cprpg_d_lanc,-- timestamp without time zone, cprpg_d_competencia,-- date, cprpgparc,-- varchar(250) cprpgdescv ) select cprempparcod,--cprpgcprempparcod integer NOT NULL, v_cprcod,--cprpgcprcod integer NOT NULL, parc,--cprpgcod integer NOT NULL, case when coalesce(confusadtentregaparagerarfin, 'N')= 'S' and rec_pv.pvdtentrega is not null then (v_datahorasaida::date + prazo[parc]::integer)+(DATE(rec_pv.pvdtentrega)-DATE(now())) else v_datahorasaida::date + prazo[parc]::integer end,--cprpgdvenc date, --now()::date+prazo[parc]::integer,--cprpgdvenc date, --Com ST na Primeira Parcela e verificando se a taxa de cartão tambem é aplicada na primeira parcela case when tc.tc_usa_tctaxacartao_doc = 'S' then (case when (v_DivSt = 'S') then trunc(cprvt / rec_pv.num_parc, 2) else case when parc = 1 then trunc(((cprvt - coalesce((select nfvlicmsst from nf where nfcod = cprnfcod), 0))/ rec_pv.num_parc) + coalesce((select nfvlicmsst from nf where nfcod = cprnfcod), 0), 2) else trunc((cprvt - coalesce((select nfvlicmsst from nf where nfcod = cprnfcod), 0))/ rec_pv.num_parc, 2) end end ) * (1 + coalesce(tc.tctaxacartao, 0)/ 100) else case when (v_DivSt = 'S') then trunc(cprvt / rec_pv.num_parc, 2) else case when parc = 1 then trunc(((cprvt - coalesce((select nfvlicmsst from nf where nfcod = cprnfcod), 0))/ rec_pv.num_parc) + coalesce((select nfvlicmsst from nf where nfcod = cprnfcod), 0), 2) else trunc((cprvt - coalesce((select nfvlicmsst from nf where nfcod = cprnfcod), 0))/ rec_pv.num_parc, 2) end end end, rec_pv.pvtccod,--cprpgtccod integer, 'A',--cprpgsta character(1), cprfunparcod,--cprpgfunparcod integer, v_datahorasaida::date + prazo[parc]::integer,--cprpgdvenco date, --now()::date+prazo[parc]::integer,--cprpgdvenco date, rec_pv.pvtccod,--cprpgtccodo integer, v_agora,--cprpg_d_lanc timestamp without time zone, cast(v_agora as date),--cprpg_d_competencia date, parc,--cprpgparc varchar(250) case when (v_DivSt = 'S') then round((cprvt / rec_pv.num_parc)* rec_pv.cli_perc_fin / 100, 4) else case when (parc = 1 and rec_pv.cli_tipo_perc_fin = 'N') then round((((cprvt-coalesce((select nfvlicmsst from nf where nfcod = cprnfcod), 0))/ rec_pv.num_parc)+ coalesce((select nfvlicmsst from nf where nfcod = cprnfcod), 0))* rec_pv.cli_perc_fin / 100, 4) else round((((cprvt-coalesce((select nfvlicmsst from nf where nfcod = cprnfcod), 0))/ rec_pv.num_parc))* rec_pv.cli_perc_fin / 100, 4) end end --cprpgdescv from (select regexp_split_to_array(rec_pv.plpgcondicao, ';') as prazo) p join generate_series(1, rec_pv.num_parc) parc on 1 = 1 --join cpr on cprempparcod = 1 and cprcod = 43200 join cpr on cprempparcod=p_empresa and cprcod=v_cprcod join conf on cprempparcod = confempparcod join tc on rec_pv.pvtccod = tccod; END IF; --verifica diferenca e joga na ultima parcela UPDATE cprpg a SET cprpgv = round(cprpgv,2)+p.dif FROM ( select cprempparcod, cprcod, cprvt-sum(round(coalesce(cprpgv,0),2)) as dif from cpr left join cprpg on cprcod=cprpgcprcod and cprpgcprempparcod=cprempparcod where cprcod=v_cprcod group by cprempparcod,cprcod,cprvt ) AS p WHERE cprpgcprcod=cprcod and cprpgcprempparcod=cprempparcod and cprpgcod=rec_pv.num_parc; --corrige o desconto UPDATE cprpg a SET cprpgdescv = round(cprpgv*rec_pv.cli_perc_fin/100,2) FROM ( select cprempparcod, cprcod from cpr left join cprpg on cprcod=cprpgcprcod and cprpgcprempparcod=cprempparcod where cprcod=v_cprcod group by cprempparcod,cprcod,cprvt ) AS p WHERE cprpgcprcod=cprcod and cprpgcprempparcod=cprempparcod; END IF;--IF rec_pv.opnfcpr='S' THEN --************************************************************* --TRATAMENTO DO ESTOQUE --(No momento tratando pelo pvicb, se existe entao caracteriza pedido CB. --Tratar no futuro Tipo Pedido) select pvipvcod into v_pedido from pvicb where pvipvcod = p_pedido; if found then--SE PEDIDO CESTA for rec_pv_insert_estmv in select pvcliparcod, pvipvempparcod, pvipvcod, pviprocod, pviuvecod, pviuvedes, pviuveun, pviuvemult, pviqtde, pviqtdeate, pviqtdeatecar, opnfcod, opnfsta, opnfcpr, opnfesp, opnftopnfcod from pv join cli on pvcliparcod = cliparcod join loc on cliloccod = loccod join opnf on pvopnfcod = opnfcod join plpg on pvplpgcod = plpgcod join pvicb on pvcod = pvipvcod and pvempparcod = pvipvempparcod join pro on pviprocod = procod join est on pviprocod = estprocod and pvipvempparcod = estempparcod where pviqtdeatecar>0 and opnf_nao_mov_est = 'N' and pvipvempparcod = p_empresa and pvipvcod = p_pedido loop select f_insert_estmv(rec_pv_insert_estmv.pvipvempparcod, rec_pv_insert_estmv.pviprocod, rec_pv_insert_estmv.pviuvecod, rec_pv_insert_estmv.pviuvedes, rec_pv_insert_estmv.pviuveun, rec_pv_insert_estmv.pviuvemult, 'S', rec_pv_insert_estmv.opnfsta, rec_pv_insert_estmv.pviqtdeatecar, v_VERSAO,--'FUNCAO FATURAMENTO', v_VERSAO,--'FATURAMENTO PEDIDO CESTA BASICA', v_nfcod, p_usuario, --novos campos rec_pv_insert_estmv.pvcliparcod, rec_pv_insert_estmv.opnfcod, 'SAIDA MERCADORIA' ) into rec_insert_estmv; end loop; else for rec_pv_insert_estmv in--SE PEDIDO NAO CESTA select pvcliparcod, pvipvempparcod, pvipvcod, pviprocod, pviuvecod, pviuvedes, pviuveun, pviuvemult, pviqtde, pviqtdeate, pviqtdeatecar, opnfcod, opnfsta, opnfcpr, opnfesp, opnftopnfcod, fpeforparcod from pv join cli on pvcliparcod = cliparcod join loc on cliloccod = loccod join opnf on pvopnfcod = opnfcod join plpg on pvplpgcod = plpgcod join pvi on pvcod = pvipvcod and pvempparcod = pvipvempparcod join pro on pviprocod = procod join est on pviprocod = estprocod and pvipvempparcod = estempparcod join fpe on fpeprocod = procod and fpeempparcod = estempparcod and fpetipo = 'P' where pviqtdeatecar > 0 and opnf_nao_mov_est = 'N' and pvipvempparcod = p_empresa and pvipvcod = p_pedido loop if rec_pv.opnfusaentregafutura = 'N' then select f_insert_estmv(rec_pv_insert_estmv.pvipvempparcod, rec_pv_insert_estmv.pviprocod, rec_pv_insert_estmv.pviuvecod, rec_pv_insert_estmv.pviuvedes, rec_pv_insert_estmv.pviuveun, rec_pv_insert_estmv.pviuvemult, 'S', rec_pv_insert_estmv.opnfsta, rec_pv_insert_estmv.pviqtdeatecar, v_VERSAO,--'FUNCAO FATURAMENTO', v_VERSAO,--'FATURAMENTO PEDIDO DE VENDA', v_nfcod, p_usuario, --novos campos rec_pv_insert_estmv.fpeforparcod,--rec_pv_insert_estmv.pvcliparcod, alterado temporariamente para mostrar o fornecedor do produto rec_pv_insert_estmv.opnfcod, 'SAIDA MERCADORIA' ) into rec_insert_estmv; end if; /*************************************************************** * ALIMENTA CLIEST **************************************************************/ if rec_pv.opnfusaentregafutura = 'S' then select coalesce(estcliprocod, 0) into v_cliestprocod from estcli where estcliparcod = rec_pv_insert_estmv.pvcliparcod and estcliprocod = rec_pv_insert_estmv.pviprocod and estcliuvecod = rec_pv_insert_estmv.pviuvecod; if v_cliestprocod > 0 then update estcli set estcliest = coalesce(estcliest, 0)+ rec_pv_insert_estmv.pviqtdeatecar where estcliparcod = rec_pv_insert_estmv.pvcliparcod and estcliprocod = rec_pv_insert_estmv.pviprocod and estcliuvecod = rec_pv_insert_estmv.pviuvecod; else insert into estcli (estcliparcod, estcliprocod, estcliuvecod, estcliest ) values ( rec_pv_insert_estmv.pvcliparcod,--estcliparcod, rec_pv_insert_estmv.pviprocod,--estcliprocod, rec_pv_insert_estmv.pviuvecod,--estcliuvecod, rec_pv_insert_estmv.pviqtdeatecar--estcliest ); end if;--v_cliestprocod > 0 end if;--rec_pv.opnfusaentregafutura = 'S' /*************************************************************** * ALIMENTA CLIEST **************************************************************/ end loop; end if; --************************************************************* -- TRATAMENTO LOTE --************************************************************* for rec_pv_usacontrolelote in --FILTRA ITENS DO PEDIDO QUE USA CONTROLE DE LOTE select pvcliparcod, pvipvempparcod, pvipvcod, pviprocod, pviuvecod, pviuvedes, pviuveun, pviuvemult, pviqtde, pviqtdeate, pviqtdeatecar, opnfsta, opnfcpr, opnfesp, opnftopnfcod, pvilotelotecod, pviloteqtdeatecar from pv join cli on pvcliparcod = cliparcod join loc on cliloccod = loccod join opnf on pvopnfcod = opnfcod join plpg on pvplpgcod = plpgcod join pvi on pvcod = pvipvcod and pvempparcod = pvipvempparcod join pro on pviprocod = procod join est on pviprocod = estprocod and pvipvempparcod = estempparcod join pvilote on pvipvcod = pvilotepvipvcod and pvilotepviseq = pviseq where pviqtdeatecar>0 and opnf_nao_mov_est = 'N' and estusacontrolelote = 'S' and pvcod = p_pedido and pvipvempparcod = p_empresa loop select f_insert_estlotemv( rec_pv_usacontrolelote.pvipvempparcod, rec_pv_usacontrolelote.pviprocod, rec_pv_usacontrolelote.pviuvecod, rec_pv_usacontrolelote.pviuvedes, rec_pv_usacontrolelote.pviuveun, rec_pv_usacontrolelote.pviuvemult, rec_pv_usacontrolelote.pvilotelotecod, 'S', rec_pv_usacontrolelote.opnfsta, rec_pv_usacontrolelote.pviloteqtdeatecar, v_VERSAO,--'FUNC FATURAMENTO', v_VERSAO,--'FATURAMENTO PEDIDO DE VENDA', v_nfcod, p_usuario) into rec_insert_estlotemv; insert into nfilote ( nfilotecadusuparcod, nfilotecadhorario, nfilotealtusuparcod, nfilotealthorario, nfilotenfempparcod, nfilotenfparcod, nfilotenfnum, nfilotenfserie, nfilotenfcod, nfiloteprocod, nfiloteuvecod, nfiloteuvedes, nfiloteuveun, nfiloteuvemult, nfilotelotecod, nfiloteqtde) values ( p_usuario, v_agora, null, null, rec_pv_usacontrolelote.pvipvempparcod, rec_pv_usacontrolelote.pvcliparcod, 1,--substituir no update '1',--substituir no update v_nfcod, rec_pv_usacontrolelote.pviprocod, rec_pv_usacontrolelote.pviuvecod, rec_pv_usacontrolelote.pviuvedes, rec_pv_usacontrolelote.pviuveun, rec_pv_usacontrolelote.pviuvemult, rec_pv_usacontrolelote.pvilotelotecod, rec_pv_usacontrolelote.pviloteqtdeatecar ); end loop;--FOR rec_pv_usacontrolelote IN --************************************************************* -- LIBERACAO DA QTDE RESERVADA --************************************************************* select f_tratar_reserva(p_empresa) into v_res; --************************************************************* -- GERAR PROXIMO NUM NF --************************************************************* select empresa, layout, numero, serie into rec_seqnf from f_seqnf(rec_pv.pvempparcod, rec_pv.pvopnfcod); --************************************************************* -- ATUALIZAR PROXIMO NUM NF E DEMAIS DADOS --************************************************************* update nf set nfnum = rec_seqnf.numero, nfserie = rec_seqnf.serie where nfcod = v_nfcod; update nfe set nfenfnum = rec_seqnf.numero, nfenfserie = rec_seqnf.serie where nfenfcod = v_nfcod; update nfecf set nfecfnfnum = rec_seqnf.numero, nfecfnfserie = rec_seqnf.serie where nfecfnfcod = v_nfcod; update nfi set nfinfnum = rec_seqnf.numero, nfinfserie = rec_seqnf.serie where nfinfcod = v_nfcod; update cpr set cprdocnum = rec_seqnf.numero, cprdocserie = rec_seqnf.serie, cpr_notafiscal = rec_seqnf.numero::text where cprnfcod = v_nfcod; --cprcod=v_cprcod; update pv set pvsta = 'FT', pvaltusuparcod = p_usuario, pvalthorario = now(), pvacao = 'FUNCAO FATURAMENTO' || v_VERSAO where pvcod = rec_pv.pvcod and pvempparcod = rec_pv.pvempparcod; --update car set carsta = 'FT',cartf='F' where carcod = rec_pv.pvcarcod and carempparcod = rec_pv.pvempparcod; update car set carsta = 'FT',cartf='F' where carcod = rec_pv.pvcarcod; update nfilote set nfilotenfnum = rec_seqnf.numero, nfilotenfserie = rec_seqnf.serie where nfilotenfcod = v_nfcod; -- corrige o nfivl caso a diferença de round 4 - round 2 seja maior que 0 jogando essa diferença no primeiro item if v_DescontaStdoPreco = 'S' then UPDATE nfi a SET nfivl = round(nfivl,4)+p.dif, nfibcicms = round(nfibcicms,4)+p.dif FROM ( select nfempparcod, nfcod, max(max(nfiseq)) over (partition by 1) as ultpro, sum((nfivl+nfivlicmsst+nfifcpvlqicmsst)-(round(nfivl,2)+round(nfivlicmsst,2)+round(nfifcpvlqicmsst,2))) as dif from nf join nfi on nfinfcod = nfcod where nfcod=v_nfcod group by nfempparcod,nfcod ) AS p WHERE nfiseq=ultpro and nfinfcod=v_nfcod; end if; --atualizar info sobre compras do cliente if rec_pv.opnftopnfcod in ('VE', 'VI', 'VV') then --Inserindo a Data da Primeira Compra update cli set clidpcomp = v_agora where cliparcod = rec_pv.pvcliparcod and (clidpcomp is null); --Atualizando a Data da Ultima Compra update cli set cliducomp = v_agora, cliultnfnum = rec_seqnf.numero, cliultnfserie = rec_seqnf.serie where cliparcod = rec_pv.pvcliparcod; end if; --************************************************************* -- NFIDET --************************************************************* select f_atualizar_nfidet(v_nfcod) into v_nfidet; --************************************************************* -- EFETIVACAO AUTOMATICA --************************************************************* if rec_pv.opnfcpr = 'S' then select confefetivarauto into v_efetauto from conf where confempparcod = rec_pv.pvempparcod; if coalesce(v_efetauto, 'N')= 'S' then select f_efetivar_automatico(v_nfcod) into rec_efetauto; end if; end if; --************************************************************* -- ENVIO DE MENSAGEM --************************************************************* select nextval('mensagem_mens_cod_seq') into v_menscod; insert into mensagem (mens_cod, mens_dtlan, mens_de, mens_assunto, mens_texto1, mens_texto2) values (v_menscod, now(), p_usuario, 'Faturamento realizado', 'NFe ' || cast(rec_seqnf.numero as varchar)|| ' - Faturamento realizado para o pedido: ' || cast(p_pedido as varchar), 'Cliente: ' ||( select pardes from par where parcod = ( select pvcliparcod from pv where pvcod = p_pedido))); insert into mens_para (menspara_mens_cod, menspara_para, menspara_dtreceb, menspara_dtexc) values (v_menscod, rec_pv.pvrcaparcod, null, null); if v_nfcod>0 then return QUERY select v_nfcod::integer as frfatnfcod, rec_seqnf.numero::integer as frfatnfnum, rec_seqnf.serie::text as frfatnfserie, 'Faturamento realizado'::text; else return QUERY select 0::integer as frfatnfcod, 0::integer as frfatnfnum, ''::text as frfatnfserie, 'Nenhum pedido faturado'::text; end if; --RETURN QUERY SELECT 1::integer as frfatnfcod, 1::integer as frfatnfnum, '1'::text as frfatnfserie, 'Faturamento realizado'::text; return; end; $function$ ; -- Permissions ALTER FUNCTION public.f_realizar_faturamento(int4, int4, int4, int4, timestamptz, timestamptz, int4, int4, int4) OWNER TO postgres; GRANT ALL ON FUNCTION public.f_realizar_faturamento(int4, int4, int4, int4, timestamptz, timestamptz, int4, int4, int4) TO public; GRANT ALL ON FUNCTION public.f_realizar_faturamento(int4, int4, int4, int4, timestamptz, timestamptz, int4, int4, int4) TO postgres; ------------------------------------------------------------------------------------------------