diff --git a/apps/api/src/app/catalog/catalog.service.ts b/apps/api/src/app/catalog/catalog.service.ts index c3e9628..2e85663 100644 --- a/apps/api/src/app/catalog/catalog.service.ts +++ b/apps/api/src/app/catalog/catalog.service.ts @@ -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(` - 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(` + 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(` + 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 `), diff --git a/apps/web/src/cockpits/rep/CatalogPage.tsx b/apps/web/src/cockpits/rep/CatalogPage.tsx index 1b02abb..ceb93f6 100644 --- a/apps/web/src/cockpits/rep/CatalogPage.tsx +++ b/apps/web/src/cockpits/rep/CatalogPage.tsx @@ -161,7 +161,10 @@ export function CatalogPage() { }} options={pautas?.map((p) => ({ value: p.idPauta, - label: `${p.codigo} — ${p.descricao}`, + label: + p.qtdReps != null + ? `${p.codigo} — ${p.descricao} · ${p.qtdReps} rep${p.qtdReps !== 1 ? 's' : ''}` + : `${p.codigo} — ${p.descricao}`, }))} /> diff --git a/apps/web/src/components/layout/Sidebar.tsx b/apps/web/src/components/layout/Sidebar.tsx index 509db6b..31cec56 100644 --- a/apps/web/src/components/layout/Sidebar.tsx +++ b/apps/web/src/components/layout/Sidebar.tsx @@ -92,6 +92,11 @@ const GERENTE_ITEMS: ItemType[] = [ icon: , label: 'Clientes', }, + { + key: '/catalogo', + icon: , + label: 'Catálogo', + }, { key: '/relatorios', icon: , diff --git a/libs/shared/api-interface/src/lib/product.contract.ts b/libs/shared/api-interface/src/lib/product.contract.ts index 22f8a85..4c9b923 100644 --- a/libs/shared/api-interface/src/lib/product.contract.ts +++ b/libs/shared/api-interface/src/lib/product.contract.ts @@ -27,6 +27,8 @@ export const PautaSchema = z.object({ idPauta: z.number().int(), codigo: z.number().int(), descricao: z.string(), + // Presente só para gestor: quantos representantes usam esta pauta + qtdReps: z.number().int().optional(), }); export type Pauta = z.infer;