feat: Implement granular permission-based status transitions for pedidos.
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
const historyQuery = $derived.by(() => useQuery(api.pedidos.getHistory, { pedidoId }));
|
||||
const objetosQuery = $derived.by(() => useQuery(api.objetos.list, {}));
|
||||
const acoesQuery = $derived.by(() => useQuery(api.acoes.list, {}));
|
||||
const permissionsQuery = $derived.by(() => useQuery(api.pedidos.getPermissions, { pedidoId }));
|
||||
|
||||
// Derived state
|
||||
let pedido = $derived(pedidoQuery.data);
|
||||
@@ -37,6 +38,7 @@
|
||||
let history = $derived(historyQuery.data || []);
|
||||
let objetos = $derived(objetosQuery.data || []);
|
||||
let acoes = $derived(acoesQuery.data || []);
|
||||
let permissions = $derived(permissionsQuery.data);
|
||||
|
||||
type Modalidade = 'dispensa' | 'inexgibilidade' | 'adesao' | 'consumo';
|
||||
|
||||
@@ -114,7 +116,8 @@
|
||||
itemsQuery.isLoading ||
|
||||
historyQuery.isLoading ||
|
||||
objetosQuery.isLoading ||
|
||||
acoesQuery.isLoading
|
||||
acoesQuery.isLoading ||
|
||||
permissionsQuery.isLoading
|
||||
);
|
||||
|
||||
let error = $derived(
|
||||
@@ -256,23 +259,48 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function updateStatus(
|
||||
novoStatus:
|
||||
| 'cancelado'
|
||||
| 'concluido'
|
||||
| 'em_rascunho'
|
||||
| 'aguardando_aceite'
|
||||
| 'em_analise'
|
||||
| 'precisa_ajustes'
|
||||
) {
|
||||
if (!confirm(`Confirmar alteração de status para: ${novoStatus}?`)) return;
|
||||
async function handleEnviarParaAceite() {
|
||||
if (!confirm('Enviar para aceite?')) return;
|
||||
try {
|
||||
await client.mutation(api.pedidos.updateStatus, {
|
||||
pedidoId,
|
||||
novoStatus
|
||||
});
|
||||
await client.mutation(api.pedidos.enviarParaAceite, { pedidoId });
|
||||
} catch (e) {
|
||||
alert('Erro ao atualizar status: ' + (e as Error).message);
|
||||
alert('Erro: ' + (e as Error).message);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleIniciarAnalise() {
|
||||
if (!confirm('Iniciar análise?')) return;
|
||||
try {
|
||||
await client.mutation(api.pedidos.iniciarAnalise, { pedidoId });
|
||||
} catch (e) {
|
||||
alert('Erro: ' + (e as Error).message);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleConcluir() {
|
||||
if (!confirm('Concluir pedido?')) return;
|
||||
try {
|
||||
await client.mutation(api.pedidos.concluirPedido, { pedidoId });
|
||||
} catch (e) {
|
||||
alert('Erro: ' + (e as Error).message);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSolicitarAjustes() {
|
||||
if (!confirm('Solicitar ajustes?')) return;
|
||||
try {
|
||||
await client.mutation(api.pedidos.solicitarAjustes, { pedidoId });
|
||||
} catch (e) {
|
||||
alert('Erro: ' + (e as Error).message);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleCancelar() {
|
||||
if (!confirm('Cancelar pedido?')) return;
|
||||
try {
|
||||
await client.mutation(api.pedidos.cancelarPedido, { pedidoId });
|
||||
} catch (e) {
|
||||
alert('Erro: ' + (e as Error).message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -635,42 +663,45 @@
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2">
|
||||
{#if pedido.status === 'em_rascunho' || pedido.status === 'precisa_ajustes'}
|
||||
{#if permissions?.canSendToAcceptance}
|
||||
<button
|
||||
onclick={() => updateStatus('aguardando_aceite')}
|
||||
onclick={handleEnviarParaAceite}
|
||||
class="flex items-center gap-2 rounded bg-blue-600 px-4 py-2 text-white hover:bg-blue-700"
|
||||
>
|
||||
<Send size={18} /> Enviar para Aceite
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
{#if pedido.status === 'aguardando_aceite'}
|
||||
{#if permissions?.canStartAnalysis}
|
||||
<button
|
||||
onclick={() => updateStatus('em_analise')}
|
||||
onclick={handleIniciarAnalise}
|
||||
class="flex items-center gap-2 rounded bg-indigo-600 px-4 py-2 text-white hover:bg-indigo-700"
|
||||
>
|
||||
<Clock size={18} /> Iniciar Análise
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
{#if pedido.status === 'em_analise'}
|
||||
{#if permissions?.canConclude}
|
||||
<button
|
||||
onclick={() => updateStatus('concluido')}
|
||||
onclick={handleConcluir}
|
||||
class="flex items-center gap-2 rounded bg-green-600 px-4 py-2 text-white hover:bg-green-700"
|
||||
>
|
||||
<CheckCircle size={18} /> Concluir
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
{#if permissions?.canRequestAdjustments}
|
||||
<button
|
||||
onclick={() => updateStatus('precisa_ajustes')}
|
||||
onclick={handleSolicitarAjustes}
|
||||
class="flex items-center gap-2 rounded bg-orange-500 px-4 py-2 text-white hover:bg-orange-600"
|
||||
>
|
||||
<AlertTriangle size={18} /> Solicitar Ajustes
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
{#if pedido.status !== 'cancelado' && pedido.status !== 'concluido'}
|
||||
{#if permissions?.canCancel}
|
||||
<button
|
||||
onclick={() => updateStatus('cancelado')}
|
||||
onclick={handleCancelar}
|
||||
class="flex items-center gap-2 rounded bg-red-100 px-4 py-2 text-red-700 hover:bg-red-200"
|
||||
>
|
||||
<XCircle size={18} /> Cancelar
|
||||
|
||||
Reference in New Issue
Block a user