feat(api,web): catalogo na area do gerente com todas as pautas e precos

- Menu Catalogo no cockpit do gerente (rota /catalogo existente)
- /catalog/pautas: gestor recebe TODAS as pautas ativas com contagem de
  reps que usam cada uma (rep segue vendo so as suas cod_pauta1..6)
- Detalhe do produto: gestor ve o preco em todas as pautas (rep segue
  restrito as dele)
- Select de pauta mostra "N reps" quando disponivel

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-22 20:40:34 +00:00
parent 725a94ede1
commit 756e56d8d3
4 changed files with 52 additions and 18 deletions

View File

@@ -180,29 +180,49 @@ export class CatalogService {
const idEmpresa = matrizEmpresa(this.cls.get('idEmpresa'));
const userId = this.cls.get('userId');
const codVendedor = userId ? parseInt(userId, 10) : 0;
const role = this.cls.get('role') ?? 'rep';
interface PautaRow {
id_pauta: number;
codigo: number;
descricao: string;
qtd_reps?: string;
}
const rows = await prisma.$queryRawUnsafe<PautaRow[]>(`
SELECT DISTINCT pa.id_pauta, pa.codigo, TRIM(pa.descricao) AS descricao
FROM vw_pautas pa
JOIN vw_representantes r ON pa.codigo IN (
r.cod_pauta1, r.cod_pauta2, r.cod_pauta3,
r.cod_pauta4, r.cod_pauta5, r.cod_pauta6
)
WHERE pa.id_empresa = ${idEmpresa}
AND pa.ativo = 1
AND r.codigo = ${codVendedor}
ORDER BY pa.codigo
`);
// Rep vê só as pautas atribuídas a ele (cod_pauta1..6); gestor vê TODAS as
// pautas ativas, com a contagem de reps que usam cada uma.
const rows =
role === 'rep'
? await prisma.$queryRawUnsafe<PautaRow[]>(`
SELECT DISTINCT pa.id_pauta, pa.codigo, TRIM(pa.descricao) AS descricao
FROM vw_pautas pa
JOIN vw_representantes r ON pa.codigo IN (
r.cod_pauta1, r.cod_pauta2, r.cod_pauta3,
r.cod_pauta4, r.cod_pauta5, r.cod_pauta6
)
WHERE pa.id_empresa = ${idEmpresa}
AND pa.ativo = 1
AND r.codigo = ${codVendedor}
ORDER BY pa.codigo
`)
: await prisma.$queryRawUnsafe<PautaRow[]>(`
SELECT pa.id_pauta, pa.codigo, TRIM(pa.descricao) AS descricao,
COUNT(DISTINCT r.codigo)::text AS qtd_reps
FROM vw_pautas pa
LEFT JOIN vw_representantes r ON pa.codigo IN (
r.cod_pauta1, r.cod_pauta2, r.cod_pauta3,
r.cod_pauta4, r.cod_pauta5, r.cod_pauta6
)
WHERE pa.id_empresa = ${idEmpresa}
AND pa.ativo = 1
GROUP BY pa.id_pauta, pa.codigo, pa.descricao
ORDER BY pa.codigo
`);
return rows.map((r) => ({
idPauta: Number(r.id_pauta),
codigo: Number(r.codigo),
descricao: r.descricao,
...(r.qtd_reps != null && { qtdReps: Number(r.qtd_reps) }),
}));
}
@@ -359,12 +379,16 @@ export class CatalogService {
JOIN vw_pautas pa ON pa.id_pauta = pp.id_pauta
AND pa.id_empresa = ${idEmpresa}
AND pa.ativo = 1
JOIN vw_representantes r ON pa.codigo IN (
r.cod_pauta1, r.cod_pauta2, r.cod_pauta3,
r.cod_pauta4, r.cod_pauta5, r.cod_pauta6
)
${
// Rep vê só as pautas dele; gestor vê os preços de TODAS as pautas
(this.cls.get('role') ?? 'rep') === 'rep'
? `JOIN vw_representantes r ON pa.codigo IN (
r.cod_pauta1, r.cod_pauta2, r.cod_pauta3,
r.cod_pauta4, r.cod_pauta5, r.cod_pauta6
) AND r.codigo = ${codVendedor}`
: ''
}
WHERE pp.id_produto = ${idErp}
AND r.codigo = ${codVendedor}
AND pp.preco1 > 0
ORDER BY pa.codigo
`),