Pular para o conteúdo principal

PC_DESCONTOPED - Percentual Máximo de Desconto em Pedido

Tela: MFA001 - Parâmetros de Faturamento Localização: Parâmetros → Pedidos / O.S. → Opção 1 (rótulo no formulário: % Máx Desconto Pedido) Tabela: PARMFATUR.PC_DESCONTOPED 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; DisplayFormat = '##0.00') Valor padrão: NULL (não preenchido no AfterInsert de UdmMFA001.pas — equivale a "sem limite configurado para pedidos")

Telas impactadas​

MóduloCódigoPapel
Parâmetros de FaturamentoMFA001Produtora — cadastra/edita o valor
Pedido de VendaMPD002Consumidora direta — inclui P.PC_DESCONTOPED no SELECT de BuscaParametros (o bloqueio efetivo é delegado à procedure VERIFICA_BLOQUEIO)
OrçamentoMPD004Consumidora direta — carrega iPC_DESCONTOPED da PARMFATUR para controle de desconto em orçamentos
Pedido (variante)MPD020Consumidora direta — carrega iPC_DESCONTOPED em Resultado[20] da carga de parâmetros
Troca / DevoluçãoMPD043Consumidora direta — aplica COALESCE(ITB.PC_DESCONTOMAXIMO, P.PC_DESCONTOPED) como teto de desconto (fallback por item → parâmetro da empresa). Acrescenta +10% quando ST_PACOTEFORMATURA = 'S'.
Comprovante RecapCPD009Lê no dataset de parâmetros (INSERT/UPDATE/SELECT do PARMFATUR)
RecapadoraRCA006Lê no dataset de parâmetros (INSERT/UPDATE/SELECT do PARMFATUR)

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

  • ITEMPEDIDO.PC_DESCONTOPEDIDO (campo em MPD097) → percentual de desconto por item do pedido, não o teto da empresa.
  • PARMFATUR.PC_DESCONTOMAX → limite para notas fiscais (ver PC_DESCONTOMAX). A procedura VERIFICA_BLOQUEIO usa PC_DESCONTOMAX para NFs e PC_DESCONTOPED para pedidos — são parâmetros distintos.

Procedures impactadas​

ProcedurePapel
VERIFICA_BLOQUEIOConsumidora central. Lê PARMFATUR.PC_DESCONTOPED junto com PC_DESCONTOMAX e, quando o documento é Pedido (I_TP_DOCTO = 'P'), Recapagem de pneu ('R') ou Ordem de Serviço/Orçamento ('O'), substitui V_PC_DESCONTOMAX pelo valor de V_PC_DESCONTOPED antes de comparar o desconto concedido. O bloqueio continua sendo do tipo 'W' quando o desconto ultrapassa o teto.

Campos envolvidos​

CampoTabelaDescrição
PC_DESCONTOPEDPARMFATURPercentual máximo de desconto para pedidos de venda, pedidos de recapagem (PEDIDOPNEU) e ordens de serviço / orçamentos
PC_DESCONTOMAXPARMFATURPercentual máximo para notas fiscais (troca feita pela procedure conforme I_TP_DOCTO)
ST_BLOQUEIOPEDPARMFATURLiga/desliga o bloqueio em pedidos — precisa estar em um status que ative a checagem ('Q', 'A', 'O', 'W', etc.)
VL_DESCONTO / VL_TOTPRODUTOPEDIDO / PEDIDOPNEU / ORDEMSERVICOBase de cálculo usada em VERIFICA_BLOQUEIO para obter V_PC_DESC
PC_DESCONTOMAXIMOITEMTABPRECOLimite por item — quando preenchido, tem prioridade sobre PC_DESCONTOPED em MPD043 (COALESCE(ITB.PC_DESCONTOMAXIMO, P.PC_DESCONTOPED)) e em ramo específico de VERIFICA_BLOQUEIO
ST_PACOTEFORMATURATROCAEm MPD043, quando 'S' soma +10% ao PC_DESCONTOPED (pacote de formatura)

Comportamento / Fórmula de aplicação​

O parâmetro representa o percentual máximo de desconto permitido no total de pedidos / recapagens / ordens de serviço. Toda a lógica central está na procedure VERIFICA_BLOQUEIO (Scripts/VERIFICA_BLOQUEIO.sql). Diferente de PC_DESCONTOMAX (que é o teto de NF), este campo só entra em cena quando o documento é não-nota:

-- Leitura conjunta (linhas 143-152 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, ...;

-- Pedido de venda (linha 172-174)
IF ( I_TP_DOCTO = 'P' ) THEN BEGIN
V_ST_BLOQUEIO = V_ST_BLOQUEIOPED;
V_PC_DESCONTOMAX = V_PC_DESCONTOPED; -- troca o teto
END

-- Pedido de recapagem de pneu (linha 275-278)
IF ( I_TP_DOCTO = 'R' ) THEN BEGIN
V_ST_BLOQUEIO = V_ST_BLOQUEIOPED;
V_PC_DESCONTOMAX = V_PC_DESCONTOPED;
END

-- Ordem de Serviço / Orçamento (linhas 352-356)
IF (I_TP_DOCTO = 'S') THEN V_ST_BLOQUEIO = V_TP_BLOQUEIOOS;
IF (I_TP_DOCTO = 'O') THEN V_ST_BLOQUEIO = V_ST_BLOQUEIOPED;
V_PC_DESCONTOMAX = V_PC_DESCONTOPED;

A partir daí, a mesma faixa de bloqueio usada para NF é reaproveitada — só que com o valor de PC_DESCONTOPED:

-- Faixa principal de comparação (linhas 1096-1106)
IF ( V_PC_DESCONTOMAX IS NOT NULL ) THEN BEGIN
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 = V_DS_BLOQUEIO ||
'O Percentual de Desconto está acima do Máximo Permitido. ' ||
'Desconto Concedido(%).: ' || REPLACE(V_PC_DESC,'.',',') || '. ' ||
'Desconto Permitido(%).: ' || REPLACE(V_PC_DESCONTOMAX,'.',',');
END
END

Fórmula: PC_DESC_CONCEDIDO = (VL_DESCONTO × 100) / VL_TOTPRODUTO. Se o resultado for maior que PC_DESCONTOPED (após a troca V_PC_DESCONTOMAX := V_PC_DESCONTOPED), dispara bloqueio do tipo 'W' com a mesma mensagem usada para nota.

Uso específico em Troca/Devolução — MPD043​

MPD043 faz a própria checagem em Delphi (não delega a VERIFICA_BLOQUEIO):

// source/MPD043/UMPD043.pas:961-965 — busca com fallback por item
Consulta := ' SELECT COALESCE(ITB.PC_DESCONTOMAXIMO, P.PC_DESCONTOPED) ' +
' FROM PARMFATUR P ' +
' LEFT JOIN ITEMTABPRECO ITB ON (ITB.CD_TABPRECO = ' + Resultado[0] +
' AND ITB.CD_ITEM = ' + dmMPD043.tabITEMCD_ITEM.AsString + ')' +
' WHERE P.CD_EMPRESA = ' + IntToStr(sessao.empresa.cd_empresa);
// source/MPD043/UMPD043.pas:3355-3362 — validação do desconto na troca
if ( vl_desconto > 0 ) then begin
Resultado := ExecutaConsulta(dmMPD043.transaction,
'SELECT COALESCE(P.PC_DESCONTOPED,0) FROM PARMFATUR P WHERE P.CD_EMPRESA = '
+ IntToStr(sessao.empresa.cd_empresa));
vl_final := ((vl_desconto*100) / Vl_final);
Vl_final := RoundTo(Vl_final,-2);
if (dmMPD043.tabTROCAST_PACOTEFORMATURA.AsString = 'S') then begin
Resultado[0] := FloatToStr(StrToFloat(Resultado[0]) + 10); // pacote de formatura: +10%
end;

Ou seja, em troca de formatura o teto efetivo é PC_DESCONTOPED + 10.

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 para pedidos — após a troca V_PC_DESCONTOMAX := V_PC_DESCONTOPED, a guarda IF (V_PC_DESCONTOMAX IS NOT NULL) THEN ... (linha 1096) pula a checagem
MPD043COALESCE(P.PC_DESCONTOPED, 0) faz o NULL virar 0, o que equivale a proibir desconto (ver comportamento abaixo) — esse é um ponto de atenção: o padrão da empresa difere entre fluxos
Fallback por item (MPD043)Se ITEMTABPRECO.PC_DESCONTOMAXIMO estiver preenchido para o produto, o COALESCE usa esse limite antes do parâmetro da empresa

Resultado esperado: no fluxo geral de pedidos (VERIFICA_BLOQUEIO), o sistema não impõe teto. Em MPD043, porém, o COALESCE(...,0) torna o valor NULL equivalente a 0 — qualquer desconto concedido é bloqueado.

Valor = 0​

AspectoComportamento
Bloqueio em VERIFICA_BLOQUEIOZero desconto permitido em pedidos. A guarda IS NOT NULL passa e a comparação V_PC_DESC > 0 bloqueia qualquer desconto positivo
MPD043Mesma lógica — qualquer vl_desconto > 0 excede o teto
Validação no próprio MFA001Não existe OnValidate para este campo (diferente de PC_DESCONTOMAX, que rejeita negativos). Ou seja, é possível gravar 0 e até valores negativos sem mensagem — a proteção só vem do tipo NUMERIC(3,2), que exige valor ≥ 0 na sintaxe

Resultado esperado: equivale a proibir descontos em pedidos (exceto se o item tiver limite próprio via ITEMTABPRECO.PC_DESCONTOMAXIMO).

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

AspectoComportamento
Teto aceito sem bloqueioVL_DESCONTO / VL_TOTPRODUTO × 100 ≤ PC_DESCONTOPED
Acima do tetoBloqueio 'W' 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 MPD002, MPD020, MPD011 etc. no salvamento/fechamento do pedido — ou validação direta em MPD043

Simulação passo a passo​

  1. MFA001 → aba Parâmetros → Pedidos / O.S. → Opção 1 → campo % Máx Desconto Pedido = 5,00.
  2. Aba Parâmetros → Faturamento → Opção 1 → campo % Máx Desconto Nota (PC_DESCONTOMAX) = 10,00 (para enxergar a bifurcação).
  3. ST_BLOQUEIOPED precisa estar em um status que ative a checagem de desconto (ex.: 'O' ou 'W').
  4. Salve os parâmetros (F6).
  5. Emita um pedido (MPD002) com total de produtos VL_TOTPRODUTO = R$ 1.000,00:
    • Desconto R$ 40,00 (4%) → V_PC_DESC = 4 ≤ 5 → salva normalmente.
    • Desconto R$ 80,00 (8%) → V_PC_DESC = 8 > 5 → bloqueia o pedido com:

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

  6. Converta o mesmo pedido em NF (MNF002) com o mesmo desconto (8%):
    • Agora I_TP_DOCTO = 'N' → a procedure não troca V_PC_DESCONTOMAX pelo PC_DESCONTOPED; usa o limite de NF (10,00).
    • V_PC_DESC = 8 ≤ 10 → NF salva normalmente.

Resultado esperado: o mesmo desconto (8%) que é bloqueado no pedido passa sem bloqueio na NF. Essa é a razão de existência do parâmetro: permitir políticas diferentes para pedido e nota (tipicamente pedido mais restrito, NF mais permissiva ou vice-versa).

Simulação em troca de formatura (MPD043)​

  1. PC_DESCONTOPED = 5,00.
  2. Troca com ST_PACOTEFORMATURA = 'S' e vl_desconto = 12% de Vl_final:
    • Teto efetivo = 5 + 10 = 15. → permite.
  3. Mesma troca com ST_PACOTEFORMATURA = 'N':
    • Teto efetivo = 5. → bloqueia.

Interação com outros parâmetros​

ParâmetroEfeito combinado
PARMFATUR.PC_DESCONTOMAXComplementar. PC_DESCONTOPED é o teto de pedido/recapagem/OS; PC_DESCONTOMAX é o teto de NF. A procedure VERIFICA_BLOQUEIO escolhe um dos dois conforme I_TP_DOCTO ('N' → PC_DESCONTOMAX; 'P'/'R'/'O' → PC_DESCONTOPED).
PARMFATUR.ST_BLOQUEIOPEDHabilita a checagem. Sem um status que ative a comparação de desconto ('Q', 'A', 'O', 'W', etc.), PC_DESCONTOPED é lido mas nunca testado — a procedure nem entra no ramo.
ITEMTABPRECO.PC_DESCONTOMAXIMOPrioridade por item. Em MPD043 o COALESCE(ITB.PC_DESCONTOMAXIMO, P.PC_DESCONTOPED) faz o limite por item prevalecer; em VERIFICA_BLOQUEIO o ramo V_PC_DESCONTOMAXIMOPRODUTO IS NOT NULL também tem precedência (bloqueio 'E').
PARMDESCONTO.PC_DESCONTO (faixa por faturamento)Teto adicional via faixa de cliente. Em VERIFICA_BLOQUEIO a variável V_PC_DESCONTOPED é reutilizada (linhas 1150-1167) para guardar o % de desconto da faixa de faturamento médio — se o desconto concedido ultrapassa a faixa, dispara bloqueio 'Y'. Isso é independente do parâmetro PARMFATUR.PC_DESCONTOPED, mas compartilha o mesmo nome de variável interna.
TROCA.ST_PACOTEFORMATURA (MPD043)Quando 'S', soma +10% ao teto efetivo (PC_DESCONTOPED + 10).
PARMUSUARIO.PC_DESCONTOMAX (ADM012)Limite por usuário aplicado em outras procedures/módulos — não substitui nem participa diretamente desta checagem em pedidos (atua em fluxos financeiros).
Sem OnValidate no MFA001Diferente de PC_DESCONTOMAX (que tem tabPARMFATURPC_DESCONTOMAXValidate rejeitando valor < 0), PC_DESCONTOPED não tem validação em tela — confia apenas no tipo NUMERIC(3,2) do Firebird.

Referências no Código Fonte​

Delphi​

ArquivoLinhasPapel
source/MFA001/UMFA001.dfm7846-7858, 8545-8561Label lbl36 = '% Máx Desconto Pedido' (pai: pagPedidoOp1 → GroupBox "Parâmetros de Pedidos/ Ordem de Serviço") e TDBEdit edtPC_DESCONTOPED (DataField=PC_DESCONTOPED)
source/MFA001/UMFA001.pas308Declaração de edtPC_DESCONTOPED: TDBEdit
source/MFA001/UdmMFA001.dfm103, 907-913, 2355, 2504, 2695, 2983Field TBCDField (Precision=4, Size=2, DisplayFormat='##0.00'); cláusulas SELECT/INSERT/UPDATE do PARMFATUR incluindo PC_DESCONTOPED
source/MFA001/UdmMFA001.pas90Declaração do field tabPARMFATURPC_DESCONTOPED: TBCDField. Nenhum OnValidate nem atribuição de padrão em AfterInsert.
source/MPD002/UdmMPD002.pas5740BuscaParametros inclui P.PC_DESCONTOPED no SELECT (posição 22 do array de resultados)
source/MPD004/UdmMPD004.pas315, 372, 389Declara iPC_DESCONTOPED: String; SELECT de PARMFATUR; atribui iPC_DESCONTOPED := Resultado[12] no carregamento do orçamento
source/MPD020/UdmMPD020.pas239, 321, 357Declara iPC_DESCONTOPED: String; SELECT de PARMFATUR; atribui iPC_DESCONTOPED := Resultado[20]
source/MPD043/UMPD043.pas961-965, 3355-3362Consumo direto — usa COALESCE(ITB.PC_DESCONTOMAXIMO, P.PC_DESCONTOPED) para o teto por item, e COALESCE(P.PC_DESCONTOPED, 0) no bloqueio final (com +10 para pacote de formatura)
source/CPD009/UdmCPD009.dfm360, 441, 557Leitura no dataset de parâmetros (INSERT/UPDATE/SELECT de PARMFATUR)
source/RCA006/UdmRCA006.dfm3109, 3190, 3306Leitura no dataset de parâmetros (INSERT/UPDATE/SELECT de PARMFATUR)

SQL (Firebird)​

ArquivoLinhasPapel
Scripts/VERIFICA_BLOQUEIO.sql23, 143-152, 172-174, 277-278, 356, 1096-1106, 1150-1167Procedure central. Lê PC_DESCONTOPED em conjunto com PC_DESCONTOMAX e, para I_TP_DOCTO em {'P','R','O'}, substitui o teto (V_PC_DESCONTOMAX := V_PC_DESCONTOPED). Aplica bloqueio 'W' quando o % concedido ultrapassa. A mesma variável interna V_PC_DESCONTOPED é reutilizada (linhas 1150-1167) para o teto por faixa de faturamento (PARMDESCONTO), gerando bloqueio 'Y'.
docs/schema/tables/PARMFATUR.sql47DDL: PC_DESCONTOPED DOM_NUMERIC3_2