feat(erp): pedidos e dashboard leem histórico do ERP (vw_pedidos_erp)
- OrdersService.list: substitui sar.pedidos por vw_pedidos_erp — 44k pedidos
históricos do rep 29 visíveis; sar.pedidos continua sendo a tabela de escrita
para novos pedidos SAR que serão integrados ao ERP
- DashboardService: atingido/pedidosMes/recentes/inativos todos via vw_pedidos_erp;
supervisor usa vw_pedidos_erp para pedidosDia
- PedidoSummarySchema: id relaxado de uuid() para string(); adiciona numero,
statusDescr e fonte ('sar'|'erp')
- orders.ts: corrige bug — apiFetch retorna JSON diretamente, não Response;
remove res.ok/res.json() incorretos
- OrdersPage: coluna Nº mostra numero do ERP; statusDescr no badge
- DevLogin: atualiza para PAVEI COMERCIO cod 29
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -38,48 +38,65 @@ export class OrdersService {
|
||||
const codVendedor = userId ? parseInt(userId, 10) : 0;
|
||||
|
||||
const { idCliente, situa, numPedSar, from, to, page, limit } = query;
|
||||
const skip = (page - 1) * limit;
|
||||
const offset = (page - 1) * limit;
|
||||
|
||||
const repFilter = role === 'rep' ? { codVendedor } : {};
|
||||
const vendedorFilter = role === 'rep' ? `AND e.cod_vendedor = ${codVendedor}` : '';
|
||||
const clienteFilter = idCliente != null ? `AND e.id_cliente = ${idCliente}` : '';
|
||||
const situaFilter = situa != null ? `AND e.situa = ${situa}` : '';
|
||||
const pedSarFilter = numPedSar ? `AND TRIM(e.num_ped_sar) ILIKE '%${numPedSar}%'` : '';
|
||||
const fromFilter = from ? `AND e.dt_pedido >= '${from}'` : '';
|
||||
const toFilter = to ? `AND e.dt_pedido <= '${to}'` : '';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const where: any = {
|
||||
idEmpresa,
|
||||
...repFilter,
|
||||
...(idCliente != null ? { idCliente } : {}),
|
||||
...(situa != null ? { situa } : {}),
|
||||
...(numPedSar ? { numPedSar: { contains: numPedSar } } : {}),
|
||||
...(from || to
|
||||
? {
|
||||
dtPedido: {
|
||||
...(from ? { gte: new Date(from) } : {}),
|
||||
...(to ? { lte: new Date(to) } : {}),
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
};
|
||||
const filters = `
|
||||
WHERE e.id_empresa = ${idEmpresa}
|
||||
${vendedorFilter} ${clienteFilter} ${situaFilter}
|
||||
${pedSarFilter} ${fromFilter} ${toFilter}
|
||||
`;
|
||||
|
||||
const [rows, total] = await Promise.all([
|
||||
prisma.pedido.findMany({
|
||||
where,
|
||||
skip,
|
||||
take: limit,
|
||||
orderBy: { dtPedido: 'desc' },
|
||||
}),
|
||||
prisma.pedido.count({ where }),
|
||||
interface ErpRow {
|
||||
id_pedido: number;
|
||||
num_ped_sar: string;
|
||||
numero: number;
|
||||
id_cliente: number;
|
||||
cod_vendedor: number;
|
||||
situa: number;
|
||||
status_descr: string;
|
||||
dt_pedido: Date;
|
||||
total: string;
|
||||
desconto_perc: string;
|
||||
obs: string | null;
|
||||
}
|
||||
|
||||
const [rows, countRows] = await Promise.all([
|
||||
prisma.$queryRawUnsafe<ErpRow[]>(`
|
||||
SELECT e.id_pedido, e.num_ped_sar, e.numero, e.id_cliente, e.cod_vendedor,
|
||||
e.situa, e.status_descr, e.dt_pedido, e.total::text, e.desconto_perc::text, e.obs
|
||||
FROM vw_pedidos_erp e
|
||||
${filters}
|
||||
ORDER BY e.dt_pedido DESC
|
||||
LIMIT ${limit} OFFSET ${offset}
|
||||
`),
|
||||
prisma.$queryRawUnsafe<[{ count: string }]>(`
|
||||
SELECT COUNT(*)::text AS count FROM vw_pedidos_erp e ${filters}
|
||||
`),
|
||||
]);
|
||||
|
||||
const total = Number(countRows[0]?.count ?? 0);
|
||||
|
||||
const data: PedidoSummary[] = rows.map((o) => ({
|
||||
id: o.id,
|
||||
numPedSar: o.numPedSar,
|
||||
idCliente: o.idCliente,
|
||||
codVendedor: o.codVendedor,
|
||||
situa: o.situa,
|
||||
dtPedido: o.dtPedido.toISOString(),
|
||||
total: decimalToString(o.total),
|
||||
descontoPerc: decimalToString(o.descontoPerc),
|
||||
obs: o.obs,
|
||||
createdAt: o.createdAt.toISOString(),
|
||||
id: `erp-${o.id_pedido}`,
|
||||
numPedSar: (o.num_ped_sar ?? '').trim(),
|
||||
numero: Number(o.numero),
|
||||
idCliente: Number(o.id_cliente),
|
||||
codVendedor: Number(o.cod_vendedor),
|
||||
situa: Number(o.situa),
|
||||
statusDescr: o.status_descr,
|
||||
dtPedido: new Date(o.dt_pedido).toISOString(),
|
||||
total: o.total ?? '0',
|
||||
descontoPerc: o.desconto_perc ?? '0',
|
||||
obs: o.obs ?? null,
|
||||
createdAt: new Date(o.dt_pedido).toISOString(),
|
||||
fonte: 'erp',
|
||||
}));
|
||||
|
||||
return { data, total, page, limit };
|
||||
@@ -388,6 +405,7 @@ export class OrdersService {
|
||||
acrescimo: decimalToString(o.acrescimo),
|
||||
comissao: decimalToString(o.comissao),
|
||||
pedFlex: decimalToString(o.pedFlex),
|
||||
fonte: 'sar' as const,
|
||||
aprovadoPor: o.aprovadoPor,
|
||||
aprovadoEm: o.aprovadoEm?.toISOString() ?? null,
|
||||
motivoRecusa: o.motivoRecusa,
|
||||
|
||||
Reference in New Issue
Block a user