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:
@@ -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
|
||||
`),
|
||||
|
||||
@@ -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}`,
|
||||
}))}
|
||||
/>
|
||||
</Space>
|
||||
|
||||
@@ -92,6 +92,11 @@ const GERENTE_ITEMS: ItemType[] = [
|
||||
icon: <FontAwesomeIcon icon={faAddressCard} fixedWidth />,
|
||||
label: 'Clientes',
|
||||
},
|
||||
{
|
||||
key: '/catalogo',
|
||||
icon: <FontAwesomeIcon icon={faBoxesStacked} fixedWidth />,
|
||||
label: 'Catálogo',
|
||||
},
|
||||
{
|
||||
key: '/relatorios',
|
||||
icon: <FontAwesomeIcon icon={faFileInvoiceDollar} fixedWidth />,
|
||||
|
||||
@@ -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<typeof PautaSchema>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user