feat(politicas): regras de desconto por grupo/subgrupo/rep e condicoes comerciais no catalogo
- Nova tabela sar.regras_desconto (grupo, subgrupo, representante, % e vigencia; campos nulos = todos) com migration idempotente, espelho no sar-erp-schema.sql e GRANT no provision-client - CRUD manager-only em /politicas/regras + aba "Regras de Desconto" na tela de Politicas Comerciais (selects com nomes de rep/grupo/subgrupo via /politicas/grupos-produto) - GET /politicas/regras/vigentes (rep ve so as que o alcancam) e GET /politicas/promocoes/vigentes para o catalogo - Regra vigente pre-aplica o desconto no carrinho do novo pedido - Selos "Promocao"/"Cond. especial" na busca de produto, catalogo do pedido e pagina de catalogo; secao "Condicoes Comerciais" no modal de detalhe do produto (descricao, % e validade) - Empty imageStyle deprecado -> styles.image no carrinho Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -95,6 +95,7 @@ async function applyGrants(client: pg.Client, appRole: string): Promise<void> {
|
||||
sar.meta_representante,
|
||||
sar.push_subscription,
|
||||
sar.promocoes,
|
||||
sar.regras_desconto,
|
||||
sar.clientes_novos,
|
||||
sar.contatos_novos
|
||||
TO ${appRole};
|
||||
|
||||
@@ -716,6 +716,26 @@ CREATE TABLE IF NOT EXISTS sar.promocoes (
|
||||
created_by VARCHAR(100) NOT NULL
|
||||
);
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- Regras de Desconto (Politicas Comerciais - criadas pelo Gerente/Admin)
|
||||
-- Desconto liberado por grupo/subgrupo de produto e/ou representante, com
|
||||
-- vigencia. Campos nulos = "todos" (ex: cod_vendedor NULL vale para todo rep).
|
||||
-- -----------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS sar.regras_desconto (
|
||||
id SERIAL PRIMARY KEY,
|
||||
id_empresa INTEGER NOT NULL,
|
||||
descricao VARCHAR(200) NOT NULL,
|
||||
cod_grupo INTEGER,
|
||||
cod_subgrupo INTEGER,
|
||||
cod_vendedor INTEGER,
|
||||
desc_pct NUMERIC(5,2) NOT NULL,
|
||||
data_inicio DATE NOT NULL,
|
||||
data_fim DATE NOT NULL,
|
||||
ativa BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
created_by VARCHAR(100) NOT NULL
|
||||
);
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- Oportunidades (Funil de Vendas)
|
||||
-- -----------------------------------------------------------------------------
|
||||
@@ -783,6 +803,8 @@ CREATE INDEX IF NOT EXISTS idx_sar_meta_vend ON sar.meta_representante(cod_v
|
||||
CREATE INDEX IF NOT EXISTS idx_sar_alcada_vend ON sar.alcada_desconto(cod_vendedor, id_empresa);
|
||||
CREATE INDEX IF NOT EXISTS idx_sar_promo_empresa ON sar.promocoes(id_empresa);
|
||||
CREATE INDEX IF NOT EXISTS idx_sar_promo_vigente ON sar.promocoes(id_empresa, data_fim) WHERE ativa;
|
||||
CREATE INDEX IF NOT EXISTS idx_sar_regras_empresa ON sar.regras_desconto(id_empresa);
|
||||
CREATE INDEX IF NOT EXISTS idx_sar_regras_vigente ON sar.regras_desconto(id_empresa, data_fim) WHERE ativa;
|
||||
CREATE INDEX IF NOT EXISTS idx_sar_oport_vend ON sar.oportunidades(id_empresa, cod_vendedor);
|
||||
CREATE INDEX IF NOT EXISTS idx_sar_oport_etapa ON sar.oportunidades(etapa);
|
||||
CREATE INDEX IF NOT EXISTS idx_chamados_empresa_vendedor ON sar.chamados(id_empresa, cod_vendedor);
|
||||
@@ -798,6 +820,6 @@ CREATE INDEX IF NOT EXISTS idx_chamado_mensagens_chamado ON sar.chamado_mensagen
|
||||
-- GRANT INSERT, UPDATE, DELETE ON
|
||||
-- sar.pedidos, sar.pedido_itens, sar.historico_pedido,
|
||||
-- sar.alcada_desconto, sar.meta_representante, sar.push_subscription,
|
||||
-- sar.promocoes, sar.clientes_novos, sar.contatos_novos
|
||||
-- sar.promocoes, sar.regras_desconto, sar.clientes_novos, sar.contatos_novos
|
||||
-- TO <role>;
|
||||
-- =============================================================================
|
||||
|
||||
Reference in New Issue
Block a user