Pular para o conteúdo principal

PC_DESCONTOMAX - Percentual Máximo de Desconto (Nota/Pedido)

Tela: MFA001 - Parâmetros de Faturamento Localização: Parâmetros → Notas Fiscais → Parâmetros de Notas (rótulo no formulário: % Máx Desconto Nota) Tabela: PARMFATUR.PC_DESCONTOMAX Tipo: Numérico (percentual %) — DOM_NUMERIC3_2 no DDL; TBCDField com Precision=4 / Size=2 no client (faixa prática: 0,00 a 99,99) Valor padrão: NULL (não preenchido no AfterInsert — equivale a "sem limite configurado")

Telas impactadas​

MóduloCódigoPapel
Parâmetros de FaturamentoMFA001Produtora — cadastra/edita o valor
NF SaídaMNF002Lê o parâmetro em BuscaParametros_MNF002 (o bloqueio real é delegado à procedure VERIFICA_BLOQUEIO)
NF Saída SimplificadaMNF017Consumidora direta — valida em iPC_DESCONTOMAX contra VL_DESCONTO do cabeçalho
Cupom FiscalMNF008Lê em iPC_DESCONTOMAX
Pedido via Tablet/ColetaMPD011Lê em PF.PC_DESCONTOMAX
Visita (orçamento rápido)TFA018Lê em PC_DESCONTO para controlar desconto da visita
CaixaMCO006Lê o parâmetro junto com os demais do faturamento
Comprovante RecapCPD009Lê no dataset de parâmetros
RecapadoraRCA006Lê no dataset de parâmetros

Atenção — homônimos que NÃO são este parâmetro:

  • PARMUSUARIO.PC_DESCONTOMAX (tela ADM012, usada em MFC004, OFI001 e na procedure VALIDA_BLOQDESCMAXSUBGRUPO) → limite por usuário.
  • PARMORCAMENTO.PC_DESCONTOMAX (tela MFA003, consumida em MPD004/MPD044) → limite de desconto de orçamentos.
  • ITEMTABPRECO.PC_DESCONTOMAXIMO (tela TFA006) → limite de desconto por item/tabela de preço.

Procedures impactadas​

ProcedurePapel
VERIFICA_BLOQUEIOConsumidora principal. Lê PARMFATUR.PC_DESCONTOMAX e PARMFATUR.PC_DESCONTOPED e aplica os bloqueios 'W' (desconto acima do máximo) e 'Q' (valor líquido abaixo do permitido) quando ST_BLOQUEIONF/ST_BLOQUEIOPED estão ativos.

Campos envolvidos​

CampoTabelaDescrição
PC_DESCONTOMAXPARMFATURPercentual máximo de desconto para notas fiscais (documento = 'N')
PC_DESCONTOPEDPARMFATURPercentual máximo de desconto para pedidos (documento = 'P') — é usado no lugar de PC_DESCONTOMAX quando I_TP_DOCTO = 'P'
ST_BLOQUEIONFPARMFATURLiga/desliga o bloqueio em notas (valores 'Q', 'A', 'O', 'W' ativam a checagem de desconto)
ST_BLOQUEIOPEDPARMFATUREquivalente para pedidos
VL_DESCONTO / PC_DESCONTONOTA / PEDIDO / ITEMNOTAValor/percentual de desconto concedido (é o que é comparado)
VL_TOTPRODUTONOTA / PEDIDOBase de cálculo usada em VERIFICA_BLOQUEIO para obter o V_PC_DESC
PC_DESCONTOMAXIMOITEMTABPRECOLimite por item (quando presente, tem prioridade sobre PC_DESCONTOMAX em algumas ramificações da procedure)
PC_DESCONTOMAXPARMUSUARIOLimite por usuário (parâmetro diferente, usado em financeiro / fechamento)

Comportamento / Fórmula de aplicação​

O parâmetro representa o percentual máximo de desconto permitido no total da nota/pedido. A checagem central é feita pela procedure VERIFICA_BLOQUEIO (Scripts/VERIFICA_BLOQUEIO.sql), que lê o campo em conjunto com ST_BLOQUEIONF / ST_BLOQUEIOPED:

-- Leitura (linhas 143-149 de VERIFICA_BLOQUEIO.sql)
SELECT ST_BLOQUEIONF, ST_BLOQUEIOPED, PC_DESCONTOMAX, PC_DESCONTOPED, ...
FROM PARMFATUR
WHERE CD_EMPRESA = :I_CD_EMPRESA
INTO :V_ST_BLOQUEIONF, :V_ST_BLOQUEIOPED, :V_PC_DESCONTONF, :V_PC_DESCONTOPED, ...;

-- Se o documento é Pedido, usa PC_DESCONTOPED no lugar (linha 174)
IF ( I_TP_DOCTO = 'P' ) THEN BEGIN
V_ST_BLOQUEIO = V_ST_BLOQUEIOPED;
V_PC_DESCONTOMAX = V_PC_DESCONTOPED;

A fórmula do percentual concedido, usada na faixa principal de bloqueio (linhas 1096-1106):

V_PC_DESC = (COALESCE(V_VL_DESCONTO,0) * 100) / nullif(V_VL_TOTPRODUTO,0);
IF ( V_PC_DESC > V_PC_DESCONTOMAX ) THEN BEGIN
V_TP_BLOQUEIO = V_TP_BLOQUEIO||'W';
V_DS_BLOQUEIO = 'O Percentual de Desconto está acima do Máximo Permitido. ' ||
'Desconto Concedido(%).: ' || V_PC_DESC || '. ' ||
'Desconto Permitido(%).: ' || V_PC_DESCONTOMAX;
END

Fórmula: PC_DESC_CONCEDIDO = (VL_DESCONTO × 100) / VL_TOTPRODUTO. Se o resultado for maior que PC_DESCONTOMAX, dispara bloqueio do tipo 'W' (ou 'Q', na checagem de valor líquido).

Valor = NULL (padrão ao criar o registro no MFA001)​

AspectoComportamento
Precisa estar preenchido?Não — é o estado inicial (o AfterInsert de UdmMFA001.pas não atribui valor)
Bloqueio em VERIFICA_BLOQUEIONão ocorre — a guarda IF (V_PC_DESCONTOMAX IS NOT NULL) THEN ... (linha 1096) pula a checagem
Bloqueio em MNF017Não ocorre — if (Trim(dmMNF017.iPC_DESCONTOMAX) <> '') then ... (linha 1397) pula
Fallback por itemSe ITEMTABPRECO.PC_DESCONTOMAXIMO estiver preenchido para o produto, a procedure usa o limite do item (ramo V_PC_DESCONTOMAXIMOPRODUTO)

Resultado esperado: o sistema não impõe teto de desconto pelo parâmetro da empresa. Só haverá bloqueio se o item tiver limite próprio (ITEMTABPRECO.PC_DESCONTOMAXIMO) ou se o usuário tiver limite em PARMUSUARIO.PC_DESCONTOMAX.

Valor = 0​

AspectoComportamento
Validação em tabPARMFATURPC_DESCONTOMAXValidateAceita (regra é if AsFloat < 0, 0 passa)
Bloqueio em VERIFICA_BLOQUEIOZero desconto permitido. A guarda IS NOT NULL passa e a comparação V_PC_DESC > 0 bloqueia qualquer desconto positivo
Bloqueio em MNF017Mesma lógica — qualquer VL_DESCONTO > 0 dispara a mensagem "O Percentual de Desconto está acima do Máximo Permitido."

Resultado esperado: equivale a proibir descontos (exceto se houver autorizador ou limite mais permissivo por item). Essa é a diferença fundamental entre NULL (sem limite) e 0 (zero de tolerância).

Valor > 0 (ex.: 10,00)​

AspectoComportamento
Teto aceito sem bloqueioVL_DESCONTO / VL_TOTPRODUTO × 100 ≤ PC_DESCONTOMAX
Acima do tetoBloqueio 'W' (ou 'Q' se a checagem for via valor líquido vs tabela) com mensagem "O Percentual de Desconto está acima do Máximo Permitido. Desconto Concedido(%).: X. Desconto Permitido(%).: Y."
Origem do bloqueioProcedure VERIFICA_BLOQUEIO (saída em O_TP_BLOQUEIO/O_DS_BLOQUEIO) consumida pelas telas no fluxo de salvamento

Simulação passo a passo​

  1. MFA001 → aba Ambos → Opção 1 → campo % Máx Desconto Nota = 10,00 (PC_DESCONTOMAX).
  2. Para que a checagem ocorra em NF, o ST_BLOQUEIONF precisa estar em um status que ative o teste — a procedure considera descontos em ('Q','A','O','W'...). Ajuste ST_BLOQUEIONF conforme o fluxo desejado.
  3. Salve os parâmetros (F6).
  4. Emita uma NF (MNF002 ou MNF017) com total de produtos VL_TOTPRODUTO = R$ 1.000,00.
  5. Conceda R$ 80,00 de desconto (8%). → V_PC_DESC = 8 ≤ 10 → salva normalmente.
  6. Conceda R$ 150,00 de desconto (15%). → V_PC_DESC = 15 > 10 → bloqueia com mensagem:

    O Percentual de Desconto está acima do Máximo Permitido. Desconto Concedido(%).: 15,00. Desconto Permitido(%).: 10,00

Resultado esperado: o fechamento/salvamento do documento é barrado quando o desconto total ultrapassa o percentual configurado.


Regra Geral / Interação com outros parâmetros​

  1. Pedido vs. Nota: em pedidos (I_TP_DOCTO = 'P'), VERIFICA_BLOQUEIO troca o teto para PC_DESCONTOPED. Ou seja, PC_DESCONTOMAX é, na prática, o limite de NFs; PC_DESCONTOPED é o limite de pedidos.
  2. ITEMTABPRECO.PC_DESCONTOMAXIMO tem prioridade por item: quando o produto possui limite próprio em sua tabela de preço (V_PC_DESCONTOMAXIMOPRODUTO IS NOT NULL), a procedure usa esse limite em vez do PC_DESCONTOMAX da empresa (linhas 1083-1094 de VERIFICA_BLOQUEIO.sql).
  3. PARMUSUARIO.PC_DESCONTOMAX (ADM012) é um limite adicional e independente por usuário, aplicado em outras procedures (VALIDA_BLOQDESCMAXSUBGRUPO) e nos módulos financeiros (MFC004, OFI001). Não substitui este parâmetro.
  4. Validação no próprio MFA001 (UdmMFA001.pas:1176-1180): impede gravar valor negativo — mensagem "O Percentual deve ser Maior ou Igual a Zero!". Não há limite superior implícito (99,99 pelo tipo do campo).
  5. ST_BLOQUEIONF / ST_BLOQUEIOPED precisam estar ativos para que a procedure sequer entre nos ramos que comparam o desconto — sem eles, PC_DESCONTOMAX é preenchido, mas não é testado.
  6. Comportamento especial em MNF017: o limite é comparado contra tabCABECALHOVL_DESCONTO.AsFloat (o valor de desconto, não o percentual), o que é um ponto de atenção histórico — efetivamente só funciona como esperado quando o desconto já é expresso em percentual pela tela.

Referências no Código Fonte​

Delphi​

ArquivoLinhasPapel
source/MFA001/UMFA001.dfm5995-6645Label '% Máx Desconto Nota' e TDBEdit edtPC_DESCONTOMAX (DataField=PC_DESCONTOMAX)
source/MFA001/UMFA001.pas379Declaração do edtPC_DESCONTOMAX: TDBEdit
source/MFA001/UdmMFA001.dfm86, 753-760, 2353, 2504, 2694, 2966Field TBCDField (Precision=4, Size=2, DisplayFormat='##0.00'), cláusulas SELECT/INSERT/UPDATE do PARMFATUR
source/MFA001/UdmMFA001.pas60, 366, 1176-1180Declaração do field, assinatura e corpo do OnValidate (rejeita valor < 0)
source/MNF002/UdmMNF002.pas10492BuscaParametros_MNF002 inclui P.PC_DESCONTOMAX no SELECT
source/MNF008/UdmMNF008.pas475, 652, 674, 757Declara iPC_DESCONTOMAX e popula via SELECT em PARMFATUR
source/MNF017/UMNF017.pas161, 185Carrega dmMNF017.iPC_DESCONTOMAX
source/MNF017/UdmMNF017.pas274, 1397-1405Consumo direto — bloqueia emissão com mensagem quando VL_DESCONTO > iPC_DESCONTOMAX
source/MPD011/UdmMPD011.pas1579SELECT de PF.PC_DESCONTOMAX no carregamento de parâmetros
source/TFA018/UTFA018.pas173-181SELECT e uso em PC_DESCONTO (variável global da visita)
source/MCO006/UdmMCO006.pas2101Leitura junto com demais parâmetros de PARMFATUR
source/CPD009/UdmCPD009.dfm540Leitura para comprovante recap
source/RCA006/UdmRCA006.dfm3289Leitura no dataset de parâmetros

SQL (Firebird)​

ArquivoLinhasPapel
Scripts/VERIFICA_BLOQUEIO.sql24, 143-149, 174, 278, 356, 464, 679, 1019, 1042-1047, 1079, 1096-1106, 1187Procedure central de validação. Lê PC_DESCONTOMAX / PC_DESCONTOPED e aplica os bloqueios tipo 'W' (desconto acima do máximo) e 'Q' (valor líquido abaixo do permitido).
docs/schema/tables/PARMFATUR.sql43DDL: PC_DESCONTOMAX DOM_NUMERIC3_2

Parâmetros homônimos (outros módulos — NÃO confundir)​

ArquivoCampoContexto
source/ADM012/UdmADM012.pas / .dfmPARMUSUARIO.PC_DESCONTOMAXLimite por usuário (financeiro)
source/MFC004/UdmMFC004.pasPARMUSUARIO.PC_DESCONTOMAXBloqueio de desconto em contas a receber/pagar
source/OFI001/UdmOFI001.pasPARMUSUARIO.PC_DESCONTOMAXBloqueio em ordem de serviço
source/MFA003/UdmMFA003.*PARMORCAMENTO.PC_DESCONTOMAXLimite de orçamento
source/MPD004/UdmMPD004.pas / source/MPD044/UdmMPD044.pasPARMORCAMENTO.PC_DESCONTOMAXOrçamento de venda / produção
source/TFA006/UdmTFA006.*ITEMTABPRECO.PC_DESCONTOMAXIMOLimite por item na tabela de preço
Scripts/VALIDA_BLOQDESCMAXSUBGRUPO.sqlPARMUSUARIO.PC_DESCONTOMAXValidação de desconto máximo por subgrupo/usuário