mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-11 17:27:31 +02:00
Add a way to resynchronize order and delivery statuses
Adds a new API endpoint to manually synchronize order and delivery statuses, fixing orders not marked as 'delivered' when associated deliveries are. Includes a refresh button on the calendar for admins and toast notifications for sync results. Replit-Commit-Author: Agent Replit-Commit-Session-Id: a8a78c07-e900-425c-a577-5b4c5894379d Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/a8a78c07-e900-425c-a577-5b4c5894379d/KuIk8gU
This commit is contained in:
1 parent
eb6a61492a
commit
a512352d6b
3 files changed
+118
-8
No files matched your search
Binary file not shown.
|
After Width: | Height: | Size: 319 KiB |
@@ -1,6 +1,6 @@
|
||||
import { useState } from "react";
|
||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { ChevronLeft, ChevronRight, Plus } from "lucide-react";
|
||||
import { ChevronLeft, ChevronRight, Plus, RefreshCw } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import CalendarGrid from "@/components/CalendarGrid";
|
||||
import QuickCreateMenu from "@/components/modals/QuickCreateMenu";
|
||||
@@ -11,6 +11,7 @@ import StatsPanel from "@/components/StatsPanel";
|
||||
import { useAuthUnified } from "@/hooks/useAuthUnified";
|
||||
import { useStore } from "@/components/Layout";
|
||||
import { apiRequest } from "@/lib/queryClient";
|
||||
import { useToast } from "@/hooks/use-toast";
|
||||
import { format, startOfMonth, endOfMonth } from "date-fns";
|
||||
import { fr } from "date-fns/locale";
|
||||
|
||||
@@ -18,6 +19,7 @@ export default function Calendar() {
|
||||
const { user } = useAuthUnified();
|
||||
const { selectedStoreId } = useStore();
|
||||
const queryClient = useQueryClient();
|
||||
const { toast } = useToast();
|
||||
const [currentDate, setCurrentDate] = useState(new Date()); // Current date
|
||||
const [selectedDate, setSelectedDate] = useState<Date | null>(null);
|
||||
const [showQuickCreate, setShowQuickCreate] = useState(false);
|
||||
@@ -25,6 +27,7 @@ export default function Calendar() {
|
||||
const [showCreateOrder, setShowCreateOrder] = useState(false);
|
||||
const [showCreateDelivery, setShowCreateDelivery] = useState(false);
|
||||
const [selectedItem, setSelectedItem] = useState<any>(null);
|
||||
const [isSyncing, setIsSyncing] = useState(false);
|
||||
|
||||
const monthStart = startOfMonth(currentDate);
|
||||
const monthEnd = endOfMonth(currentDate);
|
||||
@@ -138,6 +141,41 @@ export default function Calendar() {
|
||||
setShowCreateDelivery(true);
|
||||
};
|
||||
|
||||
// Fonction pour synchroniser les statuts commandes/livraisons
|
||||
const handleSyncOrderDeliveryStatus = async () => {
|
||||
if (user?.role !== 'admin') return;
|
||||
|
||||
setIsSyncing(true);
|
||||
try {
|
||||
console.log('🔄 Starting manual sync of order-delivery status...');
|
||||
const response = await apiRequest({
|
||||
url: '/api/sync-order-delivery-status',
|
||||
method: 'POST'
|
||||
});
|
||||
|
||||
console.log('🔄 Sync result:', response);
|
||||
|
||||
toast({
|
||||
title: "Synchronisation terminée",
|
||||
description: `${response.diagnostics.ordersFixed} commande(s) corrigée(s) sur ${response.diagnostics.problematicOrdersFound} problématique(s)`,
|
||||
});
|
||||
|
||||
// Rafraîchir les données du calendrier
|
||||
queryClient.invalidateQueries({ queryKey: ['/api/orders'] });
|
||||
queryClient.invalidateQueries({ queryKey: ['/api/deliveries'] });
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Sync failed:', error);
|
||||
toast({
|
||||
title: "Erreur de synchronisation",
|
||||
description: "Impossible de synchroniser les statuts. Vérifiez la console.",
|
||||
variant: "destructive"
|
||||
});
|
||||
} finally {
|
||||
setIsSyncing(false);
|
||||
}
|
||||
};
|
||||
|
||||
const isLoading = loadingOrders || loadingDeliveries;
|
||||
|
||||
return (
|
||||
@@ -197,13 +235,27 @@ export default function Calendar() {
|
||||
<ChevronRight className="w-4 h-4" />
|
||||
</Button>
|
||||
</div>
|
||||
<Button
|
||||
onClick={() => setShowQuickCreate(true)}
|
||||
className="bg-accent hover:bg-orange-600 text-white"
|
||||
>
|
||||
<Plus className="w-4 h-4 mr-2" />
|
||||
Nouveau
|
||||
</Button>
|
||||
<div className="flex items-center space-x-2">
|
||||
{user?.role === 'admin' && (
|
||||
<Button
|
||||
onClick={handleSyncOrderDeliveryStatus}
|
||||
disabled={isSyncing}
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="text-blue-600 border-blue-600 hover:bg-blue-50"
|
||||
>
|
||||
<RefreshCw className={`w-4 h-4 mr-2 ${isSyncing ? 'animate-spin' : ''}`} />
|
||||
{isSyncing ? 'Sync...' : 'Sync Status'}
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
onClick={() => setShowQuickCreate(true)}
|
||||
className="bg-accent hover:bg-orange-600 text-white"
|
||||
>
|
||||
<Plus className="w-4 h-4 mr-2" />
|
||||
Nouveau
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -522,6 +522,64 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
}
|
||||
});
|
||||
|
||||
// Route pour diagnostiquer et synchroniser les statuts commandes/livraisons
|
||||
app.post('/api/sync-order-delivery-status', isAuthenticated, async (req: any, res) => {
|
||||
try {
|
||||
const user = await storage.getUserWithGroups(req.user.claims ? req.user.claims.sub : req.user.id);
|
||||
if (!user || user.role !== 'admin') {
|
||||
return res.status(403).json({ message: "Access denied" });
|
||||
}
|
||||
|
||||
console.log('🔄 Starting order-delivery status synchronization...');
|
||||
|
||||
// Diagnostic: Trouver les commandes avec livraisons livrées mais pas en statut "delivered"
|
||||
const orders = await storage.getOrders();
|
||||
const problematicOrders = [];
|
||||
const fixedOrders = [];
|
||||
|
||||
for (const order of orders) {
|
||||
if (order.deliveries && order.deliveries.length > 0) {
|
||||
const hasDeliveredDeliveries = order.deliveries.some(d => d.status === 'delivered');
|
||||
|
||||
if (hasDeliveredDeliveries && order.status !== 'delivered') {
|
||||
console.log(`🔍 Found problematic order: #CMD-${order.id} (status: ${order.status}) with delivered deliveries`);
|
||||
problematicOrders.push({
|
||||
orderId: order.id,
|
||||
currentStatus: order.status,
|
||||
deliveredDeliveries: order.deliveries.filter(d => d.status === 'delivered').length,
|
||||
totalDeliveries: order.deliveries.length
|
||||
});
|
||||
|
||||
// Fixer automatiquement
|
||||
try {
|
||||
await storage.updateOrder(order.id, { status: 'delivered' });
|
||||
console.log(`✅ Fixed order #CMD-${order.id} status to 'delivered'`);
|
||||
fixedOrders.push(order.id);
|
||||
} catch (error) {
|
||||
console.error(`❌ Failed to fix order #CMD-${order.id}:`, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log('🔄 Synchronization completed');
|
||||
|
||||
res.json({
|
||||
message: "Synchronization completed",
|
||||
diagnostics: {
|
||||
problematicOrdersFound: problematicOrders.length,
|
||||
ordersFixed: fixedOrders.length,
|
||||
problematicOrders,
|
||||
fixedOrders
|
||||
}
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error("❌ Error in sync operation:", error);
|
||||
res.status(500).json({ message: "Failed to synchronize statuses", error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// Deliveries routes
|
||||
app.get('/api/deliveries', isAuthenticated, async (req: any, res) => {
|
||||
try {
|
||||
|
||||
Reference in new issue
Block a user