feat(api,web): logo da empresa na impressao e cabecalho A4 compacto
- Tabela sar.config_empresa (logo em data URL por empresa matriz) com migration idempotente, espelho no schema SQL e GRANT no provision - PUT /catalog/company/logo (gerente/admin) e logoBase64 no GET /catalog/company - vale para a impressao de todos os representantes - Nova tela /ger/config "Configuracoes" com upload/preview/remocao do logo (PNG/JPG/WebP ate 500KB) - Cabecalho da impressao redesenhado: logo a esquerda, dados da empresa condensados em 3 linhas, numero/status/data compactos a direita - ocupa ~metade da altura anterior no A4 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { ForbiddenException, Injectable } from '@nestjs/common';
|
||||
import { ClsService } from 'nestjs-cls';
|
||||
import type {
|
||||
EmpresaInfo,
|
||||
UpdateLogoBody,
|
||||
FormaPagamento,
|
||||
Municipio,
|
||||
Pauta,
|
||||
@@ -101,6 +102,8 @@ export class CatalogService {
|
||||
const r = rows[0];
|
||||
if (!r) throw new Error(`Empresa matriz ${idEmpresa} não encontrada`);
|
||||
|
||||
const config = await prisma.configEmpresa.findUnique({ where: { idEmpresa } });
|
||||
|
||||
const clean = (v: string | null) => {
|
||||
const t = (v ?? '').trim();
|
||||
return t === '' ? null : t;
|
||||
@@ -120,9 +123,28 @@ export class CatalogService {
|
||||
cep: clean(r.cep),
|
||||
telefone: clean(r.telefone),
|
||||
email: clean(r.email),
|
||||
logoBase64: config?.logoBase64 ?? null,
|
||||
};
|
||||
}
|
||||
|
||||
// Logo do cabeçalho da impressão — só gerente/admin altera; vale para todos
|
||||
// os representantes da empresa (gravado na matriz, mesma fonte do company()).
|
||||
async updateLogo(body: UpdateLogoBody): Promise<void> {
|
||||
const role = this.cls.get('role') ?? 'rep';
|
||||
if (role !== 'manager' && role !== 'admin') {
|
||||
throw new ForbiddenException('Apenas gerentes podem alterar o logo da empresa');
|
||||
}
|
||||
const prisma = this.cls.get('prisma');
|
||||
if (!prisma) throw new Error('prisma não disponível no CLS');
|
||||
const idEmpresa = matrizEmpresa(this.cls.get('idEmpresa'));
|
||||
|
||||
await prisma.configEmpresa.upsert({
|
||||
where: { idEmpresa },
|
||||
create: { idEmpresa, logoBase64: body.logoBase64 },
|
||||
update: { logoBase64: body.logoBase64 },
|
||||
});
|
||||
}
|
||||
|
||||
async municipios(q?: string): Promise<Municipio[]> {
|
||||
const prisma = this.cls.get('prisma');
|
||||
if (!prisma) throw new Error('prisma não disponível no CLS');
|
||||
|
||||
Reference in New Issue
Block a user