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