fix(api): promocao/regra de desconto e teto da alcada, nao folga somada

Com alcada base 5% e regra de 15%, o limite do item era 5+15=20% e um
desconto de 18% passava na transmissao. Agora vale o MAIOR entre alcada
do grupo, promocao e regra vigente: regra de 15% bloqueia acima de 15%.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-22 18:40:06 +00:00
parent d5279576d7
commit 43daf7ad6d

View File

@@ -496,12 +496,12 @@ export class OrdersService {
// Alçada por ITEM (complementa o gate global do transmit): o desconto EFETIVO // Alçada por ITEM (complementa o gate global do transmit): o desconto EFETIVO
// de cada item — preço cobrado vs preço de tabela, combinado com o desconto // de cada item — preço cobrado vs preço de tabela, combinado com o desconto
// global — deve caber no limite do grupo do produto (alcada_desconto por // global — deve caber no maior valor entre a alçada do grupo do produto
// codGrupo; 0 = default), somado à maior folga entre promoção ativa // (alcada_desconto por codGrupo; 0 = default), a promoção ativa
// (produto/grupo) e regra de desconto vigente (grupo/subgrupo/rep). Cobre o // (produto/grupo) e a regra de desconto vigente (grupo/subgrupo/rep) — teto,
// desconto lançado no item E desconto disfarçado de preço unitário reduzido. // não soma. Cobre o desconto lançado no item E desconto disfarçado de preço
// Preço de tabela: pauta do pedido > promocional > preço base; produto sem // unitário reduzido. Preço de tabela: pauta do pedido > promocional > preço
// referência valida só pelo campo de desconto. // base; produto sem referência valida só pelo campo de desconto.
private async assertAlcadaItens( private async assertAlcadaItens(
pedido: { pedido: {
codVendedor: number; codVendedor: number;
@@ -601,9 +601,12 @@ export class OrdersService {
) )
.reduce((max, r) => Math.max(max, Number(r.descPct)), 0); .reduce((max, r) => Math.max(max, Number(r.descPct)), 0);
const limiteItem = // Promoção/regra definem TETO próprio, não somam à alçada: com alçada 5%
(codGrupo != null ? (limitMap.get(codGrupo) ?? limiteDefault) : limiteDefault) + // e regra de 15%, o máximo do item é 15% (não 20%). Vale o maior entre a
Math.max(promoPct, regraPct); // alçada do grupo e a melhor condição vigente que alcança o produto.
const alcadaBase =
codGrupo != null ? (limitMap.get(codGrupo) ?? limiteDefault) : limiteDefault;
const limiteItem = Math.max(alcadaBase, promoPct, regraPct);
// Preço de tabela: pauta do pedido > promocional (se menor) > preço base // Preço de tabela: pauta do pedido > promocional (se menor) > preço base
const precoPauta = prod?.preco_pauta != null ? Number(prod.preco_pauta) : 0; const precoPauta = prod?.preco_pauta != null ? Number(prod.preco_pauta) : 0;