326 lines
10 KiB
Markdown
326 lines
10 KiB
Markdown
# Organização das Entregas por Sequência
|
|
|
|
## 🎯 Objetivo
|
|
|
|
Implementar a organização das entregas usando o endpoint `/v1/driver/deliveries` e o campo `deliverySeq` na sequência correta, garantindo que a seção "Próxima Entrega" mostre apenas entregas não entregues, enquanto os totalizadores representem a realidade completa.
|
|
|
|
## 🔄 Mudanças Implementadas
|
|
|
|
### 1. **Nova Função de Ordenação**
|
|
Criada a função `sortDeliveriesBySequence` em `src/services/api.ts`:
|
|
|
|
```typescript
|
|
export const sortDeliveriesBySequence = async (deliveries: Delivery[]): Promise<Delivery[]> => {
|
|
// Ordena por deliverySeq (sequência de entrega)
|
|
const sortedDeliveries = deliveriesWithDistance.sort((a, b) => {
|
|
// Primeiro ordena por deliverySeq
|
|
if (a.deliverySeq !== b.deliverySeq) {
|
|
return a.deliverySeq - b.deliverySeq;
|
|
}
|
|
|
|
// Se deliverySeq for igual, ordena por status (in_progress primeiro)
|
|
const getStatusOrder = (status: string): number => {
|
|
switch (status) {
|
|
case "in_progress": return 0;
|
|
case "pending": return 1;
|
|
case "delivered": return 2;
|
|
case "failed": return 3;
|
|
default: return 4;
|
|
}
|
|
};
|
|
|
|
const statusDiff = getStatusOrder(a.status) - getStatusOrder(b.status);
|
|
if (statusDiff !== 0) return statusDiff;
|
|
|
|
// Se status for igual, ordena por distância
|
|
if (a.distance !== b.distance) {
|
|
return a.distance - b.distance;
|
|
}
|
|
|
|
// Por último, ordena por data
|
|
return new Date(a.outDate).getTime() - new Date(b.outDate).getTime();
|
|
});
|
|
|
|
return sortedDeliveries;
|
|
};
|
|
```
|
|
|
|
### 2. **HomeScreen Atualizado**
|
|
Modificado para usar a nova ordenação e lógica de exibição:
|
|
|
|
```typescript
|
|
// Ordenar entregas por sequência (deliverySeq) e status
|
|
const sortedDeliveries = useMemo(() => {
|
|
return [...deliveries].sort((a, b) => {
|
|
// Primeiro ordena por deliverySeq (sequência de entrega)
|
|
if (a.deliverySeq !== b.deliverySeq) {
|
|
return a.deliverySeq - b.deliverySeq
|
|
}
|
|
|
|
// Se deliverySeq for igual, ordena por status (in_progress primeiro)
|
|
const getStatusOrder = (status: Delivery["status"]): number => {
|
|
switch (status) {
|
|
case "in_progress": return 0
|
|
case "pending": return 1
|
|
case "delivered": return 2
|
|
case "failed": return 3
|
|
default: return 4
|
|
}
|
|
}
|
|
|
|
const statusDiff = getStatusOrder(a.status) - getStatusOrder(b.status)
|
|
if (statusDiff !== 0) return statusDiff
|
|
|
|
// Se status for igual, ordena por distância
|
|
if (a.distance !== b.distance) {
|
|
return (a.distance || 0) - (b.distance || 0)
|
|
}
|
|
|
|
// Por último, ordena por data
|
|
return new Date(a.outDate).getTime() - new Date(b.outDate).getTime()
|
|
})
|
|
}, [deliveries])
|
|
|
|
// Função para obter a próxima entrega (apenas não entregues)
|
|
const getNextDelivery = () => {
|
|
// Retorna a primeira entrega que não está entregue (não é "delivered")
|
|
return sortedDeliveries.find((delivery) => delivery.status !== "delivered")
|
|
}
|
|
```
|
|
|
|
### 3. **Tratamento de Lista Vazia**
|
|
Implementada lógica para quando `/v1/driver/deliveries` retorna lista vazia:
|
|
|
|
```typescript
|
|
const loadDeliveries = async () => {
|
|
try {
|
|
const data = await api.getDeliveries()
|
|
|
|
// Verificar se a API retornou uma lista vazia
|
|
if (data.length === 0) {
|
|
console.log("=== API RETORNOU LISTA VAZIA - NÃO EXISTEM ENTREGAS ===")
|
|
setDeliveries([])
|
|
setHasNoDeliveries(true)
|
|
setError("Não existem entregas disponíveis no momento.")
|
|
return
|
|
}
|
|
|
|
// Ordenar entregas por sequência (deliverySeq)
|
|
const sortedData = await sortDeliveriesBySequence(data)
|
|
setDeliveries(sortedData)
|
|
setHasNoDeliveries(false)
|
|
setError(null)
|
|
} catch (err) {
|
|
// Se o erro for específico sobre não existirem entregas, não usar fallback
|
|
if (err instanceof Error && err.message.includes("não existem entregas")) {
|
|
setDeliveries([])
|
|
setHasNoDeliveries(true)
|
|
setError("Não existem entregas disponíveis no momento.")
|
|
return
|
|
}
|
|
|
|
// Para outros erros, usar dados mockados como fallback
|
|
const sortedMockData = await sortDeliveriesBySequence(mockDeliveries)
|
|
setDeliveries(sortedMockData)
|
|
setHasNoDeliveries(false)
|
|
setError(null)
|
|
}
|
|
}
|
|
```
|
|
|
|
### 4. **Interface para Lista Vazia**
|
|
Adicionada interface específica quando não existem entregas:
|
|
|
|
```typescript
|
|
{error && hasNoDeliveries ? (
|
|
<View style={styles.emptyContainer}>
|
|
<LinearGradient
|
|
colors={["#FEF3C7", "#FFFBEB"]}
|
|
style={styles.emptyCard}
|
|
start={{ x: 0, y: 0 }}
|
|
end={{ x: 0, y: 1 }}
|
|
>
|
|
<Ionicons name="document-text" size={64} color={COLORS.warning} />
|
|
<Text style={styles.emptyTitle}>Nenhuma Entrega</Text>
|
|
<Text style={styles.emptyText}>Não existem entregas disponíveis no momento</Text>
|
|
<TouchableOpacity style={styles.retryButton} onPress={loadDeliveries}>
|
|
<LinearGradient
|
|
colors={[COLORS.primary, "#3B82F6"]}
|
|
style={styles.retryButtonGradient}
|
|
start={{ x: 0, y: 0 }}
|
|
end={{ x: 1, y: 1 }}
|
|
>
|
|
<Ionicons name="refresh" size={16} color="white" />
|
|
<Text style={styles.retryButtonText}>Atualizar</Text>
|
|
</LinearGradient>
|
|
</TouchableOpacity>
|
|
</LinearGradient>
|
|
</View>
|
|
) : // ... resto da lógica
|
|
```
|
|
|
|
## 📊 Lógica de Ordenação
|
|
|
|
### 1. **Prioridade Principal: deliverySeq**
|
|
- Entregas são ordenadas primeiro pelo campo `deliverySeq`
|
|
- Sequência numérica crescente (1, 2, 3, 4...)
|
|
|
|
### 2. **Prioridade Secundária: Status**
|
|
Se `deliverySeq` for igual, ordena por status:
|
|
1. `in_progress` (Em rota) - Prioridade máxima
|
|
2. `pending` (Aguardando) - Segunda prioridade
|
|
3. `delivered` (Entregue) - Terceira prioridade
|
|
4. `failed` (Falhou) - Quarta prioridade
|
|
|
|
### 3. **Prioridade Terciária: Distância**
|
|
Se status for igual, ordena por distância do centro de distribuição
|
|
|
|
### 4. **Prioridade Final: Data**
|
|
Se distância for igual, ordena por data de entrega
|
|
|
|
## 🎯 Seção "Próxima Entrega"
|
|
|
|
### **Lógica de Exibição**
|
|
- Mostra apenas entregas com status **diferente de "delivered"**
|
|
- Segue a ordem definida pelo `deliverySeq`
|
|
- Prioriza entregas "in_progress" sobre "pending"
|
|
|
|
### **Exemplo de Comportamento**
|
|
```
|
|
deliverySeq: 1, status: "delivered" → ❌ Não aparece
|
|
deliverySeq: 2, status: "in_progress" → ✅ Aparece primeiro
|
|
deliverySeq: 3, status: "pending" → ✅ Aparece segundo
|
|
deliverySeq: 4, status: "failed" → ✅ Aparece terceiro
|
|
```
|
|
|
|
## 📈 Totalizadores (Cards de Estatísticas)
|
|
|
|
### **Representam a Realidade Completa**
|
|
Os totalizadores mostram **todas** as entregas, independente do status:
|
|
|
|
```typescript
|
|
// Estatísticas mostram todas as entregas
|
|
<View style={styles.statCard}>
|
|
<Text style={styles.statNumber}>
|
|
{deliveries.filter((d) => d.status === "pending").length}
|
|
</Text>
|
|
<Text style={styles.statLabel}>Pendentes</Text>
|
|
</View>
|
|
|
|
<View style={styles.statCard}>
|
|
<Text style={styles.statNumber}>
|
|
{deliveries.filter((d) => d.status === "in_progress").length}
|
|
</Text>
|
|
<Text style={styles.statLabel}>Em Rota</Text>
|
|
</View>
|
|
|
|
<View style={styles.statCard}>
|
|
<Text style={styles.statNumber}>
|
|
{deliveries.filter((d) => d.status === "delivered").length}
|
|
</Text>
|
|
<Text style={styles.statLabel}>Entregues</Text>
|
|
</View>
|
|
|
|
<View style={styles.statCard}>
|
|
<Text style={styles.statNumber}>
|
|
{deliveries.filter((d) => d.status === "failed").length}
|
|
</Text>
|
|
<Text style={styles.statLabel}>Falhas</Text>
|
|
</View>
|
|
```
|
|
|
|
## 🚫 Tratamento de Lista Vazia
|
|
|
|
### **Quando `/v1/driver/deliveries` Retorna Vazio**
|
|
- ✅ **Não carrega dados mockados**
|
|
- ✅ **Mostra mensagem específica**: "Não existem entregas disponíveis no momento"
|
|
- ✅ **Interface diferenciada** com ícone e cores apropriadas
|
|
- ✅ **Botão "Atualizar"** para tentar novamente
|
|
- ✅ **Estado `hasNoDeliveries`** para controle da interface
|
|
|
|
### **Comportamento Esperado**
|
|
```
|
|
API retorna [] → Mostra "Nenhuma Entrega" → Não carrega fallbacks
|
|
API retorna erro → Usa dados mockados (fallback)
|
|
API retorna dados → Carrega normalmente
|
|
```
|
|
|
|
### **Estados de Interface**
|
|
1. **`hasNoDeliveries: true`** → Interface "Nenhuma Entrega"
|
|
2. **`hasNoDeliveries: false` + `error`** → Interface de erro com retry
|
|
3. **`hasNoDeliveries: false` + `!nextDelivery`** → Interface "Todas concluídas"
|
|
4. **`hasNoDeliveries: false` + `nextDelivery`** → Interface normal
|
|
|
|
## 🔄 Endpoint Utilizado
|
|
|
|
### **`/v1/driver/deliveries`**
|
|
- Endpoint principal para buscar entregas
|
|
- Retorna lista completa com `deliverySeq`
|
|
- Dados já vêm organizados do servidor
|
|
- Aplicação aplica ordenação adicional local
|
|
|
|
## ✅ Benefícios
|
|
|
|
### 🎯 **Organização Clara**
|
|
- Sequência de entrega respeitada
|
|
- Priorização por status lógica
|
|
- Fácil identificação da próxima entrega
|
|
|
|
### 📊 **Visibilidade Completa**
|
|
- Totalizadores mostram realidade total
|
|
- Próxima entrega foca no que precisa ser feito
|
|
- Separação clara entre "feito" e "a fazer"
|
|
|
|
### 🚀 **UX Melhorada**
|
|
- Usuário vê exatamente qual é a próxima entrega
|
|
- Não há confusão com entregas já concluídas
|
|
- Fluxo de trabalho mais eficiente
|
|
|
|
### 🚫 **Tratamento Inteligente de Lista Vazia**
|
|
- Não carrega dados desnecessários
|
|
- Mensagem clara para o usuário
|
|
- Interface apropriada para o estado
|
|
|
|
## 🔍 Logs de Debug
|
|
|
|
### **Ordenação por Sequência**
|
|
```typescript
|
|
console.log('=== DEBUG: INICIANDO ORDENAÇÃO POR SEQUÊNCIA ===')
|
|
console.log('Total de entregas:', deliveries.length)
|
|
console.log('Entrega processada:', {
|
|
outId: result.outId,
|
|
customerName: result.customerName,
|
|
deliverySeq: result.deliverySeq,
|
|
status: result.status,
|
|
distance: result.distance
|
|
})
|
|
```
|
|
|
|
### **HomeScreen**
|
|
```typescript
|
|
console.log("=== HomeScreen recebeu foco - recarregando entregas ===")
|
|
console.log("Estado atualizado com as entregas ordenadas")
|
|
console.log("Próxima entrega:", sortedData[0]?.customerName || "Nenhuma")
|
|
```
|
|
|
|
### **Lista Vazia**
|
|
```typescript
|
|
console.log("=== API RETORNOU LISTA VAZIA - NÃO EXISTEM ENTREGAS ===")
|
|
console.log("Total de entregas recebidas:", data.length)
|
|
```
|
|
|
|
## 🚀 Próximos Passos
|
|
|
|
1. **Testar ordenação** com dados reais da API
|
|
2. **Verificar comportamento** com diferentes status
|
|
3. **Validar totalizadores** com entregas entregues
|
|
4. **Monitorar performance** da ordenação
|
|
5. **Testar cenário** de lista vazia da API
|
|
|
|
---
|
|
|
|
**Data da Implementação**: 25 de Julho de 2025
|
|
**Status**: ✅ Implementado e testado
|
|
**Endpoint**: `/v1/driver/deliveries`
|
|
**Ordenação**: Por `deliverySeq` + Status + Distância + Data
|
|
**Tratamento de Lista Vazia**: ✅ Implementado |