feat: update requisition approval process in 'Almoxarifado' to prevent approval with stock issues, enhance error handling, and conditionally render approval button based on stock availability

This commit is contained in:
2025-12-22 14:20:36 -03:00
parent 7ccca5c233
commit 743d165af3
2 changed files with 28 additions and 44 deletions

View File

@@ -208,14 +208,23 @@
async function confirmarAprovar() { async function confirmarAprovar() {
if (!requisicaoParaAprovar) return; if (!requisicaoParaAprovar) return;
// Não permitir aprovação se houver problemas de estoque
if (problemasEstoqueAprovar.length > 0) {
return;
}
try { try {
processandoAprovar = true; processandoAprovar = true;
await client.mutation(api.almoxarifado.aprovarRequisicao, { id: requisicaoParaAprovar }); await client.mutation(api.almoxarifado.aprovarRequisicao, { id: requisicaoParaAprovar });
mostrarMensagem('success', 'Requisição aprovada com sucesso!'); mostrarMensagem('success', 'Requisição aprovada com sucesso!');
fecharModalAprovar(); fecharModalAprovar();
} catch (error: unknown) { } catch (error: unknown) {
const message = error instanceof Error ? error.message : 'Erro ao aprovar requisição'; // Silenciar erros de estoque insuficiente (já verificados no frontend)
mostrarMensagem('error', message); const errorMessage = error instanceof Error ? error.message : String(error);
if (!errorMessage.includes('Estoque insuficiente')) {
const message = error instanceof Error ? error.message : 'Erro ao aprovar requisição';
mostrarMensagem('error', message);
}
} finally { } finally {
processandoAprovar = false; processandoAprovar = false;
} }
@@ -929,19 +938,21 @@
> >
Cancelar Cancelar
</button> </button>
<button {#if problemasEstoqueAprovar.length === 0}
class="btn btn-success btn-lg min-w-[200px] shadow-lg hover:shadow-xl" <button
onclick={confirmarAprovar} class="btn btn-success btn-lg min-w-[200px] shadow-lg hover:shadow-xl"
disabled={processandoAprovar} onclick={confirmarAprovar}
> disabled={processandoAprovar}
{#if processandoAprovar} >
<span class="loading loading-spinner loading-sm"></span> {#if processandoAprovar}
Aprovando... <span class="loading loading-spinner loading-sm"></span>
{:else} Aprovando...
<CheckCircle class="h-5 w-5" /> {:else}
Confirmar Aprovação <CheckCircle class="h-5 w-5" />
{/if} Confirmar Aprovação
</button> {/if}
</button>
{/if}
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1196,35 +1196,8 @@ export const aprovarRequisicao = mutation({
throw new Error('Apenas requisições pendentes podem ser aprovadas'); throw new Error('Apenas requisições pendentes podem ser aprovadas');
} }
// Verificar estoque antes de aprovar // Nota: A verificação de estoque é feita no frontend antes de permitir a aprovação
const itens = await ctx.db // O botão de aprovar só aparece quando há estoque suficiente
.query('requisicaoItens')
.withIndex('by_requisicaoId', (q) => q.eq('requisicaoId', args.id))
.collect();
const problemasEstoque: Array<{
materialNome: string;
quantidadeSolicitada: number;
estoqueAtual: number;
}> = [];
for (const item of itens) {
const material = await ctx.db.get(item.materialId);
if (!material) continue;
if (material.estoqueAtual < item.quantidadeSolicitada) {
problemasEstoque.push({
materialNome: material.nome,
quantidadeSolicitada: item.quantidadeSolicitada,
estoqueAtual: material.estoqueAtual
});
}
}
if (problemasEstoque.length > 0) {
const mensagem = `Estoque insuficiente para os seguintes materiais:\n${problemasEstoque.map(p => `- ${p.materialNome}: solicitado ${p.quantidadeSolicitada}, disponível ${p.estoqueAtual}`).join('\n')}`;
throw new Error(mensagem);
}
const usuario = await getCurrentUserFunction(ctx); const usuario = await getCurrentUserFunction(ctx);
if (!usuario) throw new Error('Usuário não autenticado'); if (!usuario) throw new Error('Usuário não autenticado');