Regras de Desconto (Politicas Comerciais): - Nova dimensao de escopo por pauta de precos: cria 1 regra por pauta selecionada (idPautas[]), aplicada a todos os produtos da pauta. - Coluna id_pauta em sar.regras_desconto (migration idempotente + schema canonico); motor de alcada (orders) casa regra<->pedido por idPauta. - Remove a aba/endpoints "Desconto por Representante" (gestao de alcada_desconto); o teto por rep continua no motor (default 5%) e no carrinho (/politicas/alcada), agora liberado via Regra de Desconto. Aba Equipe do gerente: - GET /equipe/supervisores: cards de disputa por supervisor (faturamento, meta, positivacao, variacao mensal, reps ativos). - SupervisorDetalheModal: detalhe do time (ranking + positivacao) reusando /dashboard/supervisor escopado por codSupervisor. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
46 lines
1.6 KiB
TypeScript
46 lines
1.6 KiB
TypeScript
import { z } from 'zod';
|
|
|
|
export const RepStatsSchema = z.object({
|
|
codVendedor: z.number().int(),
|
|
nomeVendedor: z.string().nullable(),
|
|
pedidosMes: z.number().int(),
|
|
faturamentoMes: z.number(),
|
|
ticketMedio: z.number(),
|
|
pctMeta: z.number(),
|
|
});
|
|
export type RepStats = z.infer<typeof RepStatsSchema>;
|
|
|
|
export const EquipeResponseSchema = z.object({
|
|
reps: z.array(RepStatsSchema),
|
|
totalReps: z.number().int(),
|
|
syncedAt: z.iso.datetime(),
|
|
});
|
|
export type EquipeResponse = z.infer<typeof EquipeResponseSchema>;
|
|
|
|
// Card de disputa/análise por supervisor na aba Equipe (visão gerente/admin).
|
|
// Time = reps cujo cod_supervisor aponta para este supervisor + o próprio
|
|
// supervisor (mesma semântica de getTeamCodes). Métricas agregadas do time no mês.
|
|
export const SupervisorCardSchema = z.object({
|
|
codSupervisor: z.number().int(),
|
|
nomeSupervisor: z.string().nullable(),
|
|
faturamentoMes: z.number(),
|
|
faturamentoMesAnterior: z.number(),
|
|
variacaoPct: z.number().nullable(), // null quando não há base no mês anterior
|
|
pedidosMes: z.number().int(),
|
|
ticketMedio: z.number(),
|
|
metaTotal: z.number(),
|
|
pctMeta: z.number(),
|
|
totalClientes: z.number().int(),
|
|
clientesPositivados: z.number().int(),
|
|
pctPositivacao: z.number(),
|
|
repsTotal: z.number().int(),
|
|
repsAtivos: z.number().int(), // reps do time que faturaram no mês
|
|
});
|
|
export type SupervisorCard = z.infer<typeof SupervisorCardSchema>;
|
|
|
|
export const SupervisoresResponseSchema = z.object({
|
|
supervisores: z.array(SupervisorCardSchema),
|
|
syncedAt: z.iso.datetime(),
|
|
});
|
|
export type SupervisoresResponse = z.infer<typeof SupervisoresResponseSchema>;
|