Add procurement management logic
This commit is contained in:
@@ -13,6 +13,21 @@ export { useNotification } from './useNotification';
|
||||
export { useOnboarding, useOnboardingStep } from './useOnboarding';
|
||||
export { useInventory, useInventoryDashboard, useInventoryItem, useInventoryProducts } from './useInventory';
|
||||
export { useRecipes, useProduction } from './useRecipes';
|
||||
export {
|
||||
useCurrentProcurementPlan,
|
||||
useProcurementPlanByDate,
|
||||
useProcurementPlan,
|
||||
useProcurementPlans,
|
||||
usePlanRequirements,
|
||||
useCriticalRequirements,
|
||||
useProcurementDashboard,
|
||||
useGenerateProcurementPlan,
|
||||
useUpdatePlanStatus,
|
||||
useTriggerDailyScheduler,
|
||||
useProcurementHealth,
|
||||
useProcurementPlanDashboard,
|
||||
useProcurementPlanActions
|
||||
} from './useProcurement';
|
||||
|
||||
// Import hooks for combined usage
|
||||
import { useAuth } from './useAuth';
|
||||
|
||||
294
frontend/src/api/hooks/useProcurement.ts
Normal file
294
frontend/src/api/hooks/useProcurement.ts
Normal file
@@ -0,0 +1,294 @@
|
||||
// ================================================================
|
||||
// frontend/src/api/hooks/useProcurement.ts
|
||||
// ================================================================
|
||||
/**
|
||||
* React hooks for procurement planning functionality
|
||||
*/
|
||||
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { procurementService } from '../services/procurement.service';
|
||||
import type {
|
||||
ProcurementPlan,
|
||||
GeneratePlanRequest,
|
||||
GeneratePlanResponse,
|
||||
DashboardData,
|
||||
ProcurementRequirement,
|
||||
PaginatedProcurementPlans
|
||||
} from '../types/procurement';
|
||||
|
||||
// ================================================================
|
||||
// QUERY KEYS
|
||||
// ================================================================
|
||||
|
||||
export const procurementKeys = {
|
||||
all: ['procurement'] as const,
|
||||
plans: () => [...procurementKeys.all, 'plans'] as const,
|
||||
plan: (id: string) => [...procurementKeys.plans(), id] as const,
|
||||
currentPlan: () => [...procurementKeys.plans(), 'current'] as const,
|
||||
planByDate: (date: string) => [...procurementKeys.plans(), 'date', date] as const,
|
||||
plansList: (filters?: any) => [...procurementKeys.plans(), 'list', filters] as const,
|
||||
requirements: () => [...procurementKeys.all, 'requirements'] as const,
|
||||
planRequirements: (planId: string) => [...procurementKeys.requirements(), 'plan', planId] as const,
|
||||
criticalRequirements: () => [...procurementKeys.requirements(), 'critical'] as const,
|
||||
dashboard: () => [...procurementKeys.all, 'dashboard'] as const,
|
||||
};
|
||||
|
||||
// ================================================================
|
||||
// PROCUREMENT PLAN HOOKS
|
||||
// ================================================================
|
||||
|
||||
/**
|
||||
* Hook to fetch the current day's procurement plan
|
||||
*/
|
||||
export function useCurrentProcurementPlan() {
|
||||
return useQuery({
|
||||
queryKey: procurementKeys.currentPlan(),
|
||||
queryFn: () => procurementService.getCurrentPlan(),
|
||||
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||
refetchInterval: 10 * 60 * 1000, // Refetch every 10 minutes
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to fetch procurement plan by date
|
||||
*/
|
||||
export function useProcurementPlanByDate(date: string, enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: procurementKeys.planByDate(date),
|
||||
queryFn: () => procurementService.getPlanByDate(date),
|
||||
enabled: enabled && !!date,
|
||||
staleTime: 30 * 60 * 1000, // 30 minutes for historical data
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to fetch procurement plan by ID
|
||||
*/
|
||||
export function useProcurementPlan(planId: string, enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: procurementKeys.plan(planId),
|
||||
queryFn: () => procurementService.getPlanById(planId),
|
||||
enabled: enabled && !!planId,
|
||||
staleTime: 10 * 60 * 1000, // 10 minutes
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to fetch paginated list of procurement plans
|
||||
*/
|
||||
export function useProcurementPlans(params?: {
|
||||
status?: string;
|
||||
startDate?: string;
|
||||
endDate?: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
}) {
|
||||
return useQuery({
|
||||
queryKey: procurementKeys.plansList(params),
|
||||
queryFn: () => procurementService.listPlans(params),
|
||||
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||
});
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// REQUIREMENTS HOOKS
|
||||
// ================================================================
|
||||
|
||||
/**
|
||||
* Hook to fetch requirements for a specific plan
|
||||
*/
|
||||
export function usePlanRequirements(
|
||||
planId: string,
|
||||
filters?: {
|
||||
status?: string;
|
||||
priority?: string;
|
||||
},
|
||||
enabled = true
|
||||
) {
|
||||
return useQuery({
|
||||
queryKey: procurementKeys.planRequirements(planId),
|
||||
queryFn: () => procurementService.getPlanRequirements(planId, filters),
|
||||
enabled: enabled && !!planId,
|
||||
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to fetch critical requirements across all plans
|
||||
*/
|
||||
export function useCriticalRequirements() {
|
||||
return useQuery({
|
||||
queryKey: procurementKeys.criticalRequirements(),
|
||||
queryFn: () => procurementService.getCriticalRequirements(),
|
||||
staleTime: 2 * 60 * 1000, // 2 minutes for critical data
|
||||
refetchInterval: 5 * 60 * 1000, // Refetch every 5 minutes
|
||||
});
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// DASHBOARD HOOKS
|
||||
// ================================================================
|
||||
|
||||
/**
|
||||
* Hook to fetch procurement dashboard data
|
||||
*/
|
||||
export function useProcurementDashboard() {
|
||||
return useQuery({
|
||||
queryKey: procurementKeys.dashboard(),
|
||||
queryFn: () => procurementService.getDashboardData(),
|
||||
staleTime: 2 * 60 * 1000, // 2 minutes
|
||||
refetchInterval: 5 * 60 * 1000, // Refetch every 5 minutes
|
||||
});
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// MUTATION HOOKS
|
||||
// ================================================================
|
||||
|
||||
/**
|
||||
* Hook to generate a new procurement plan
|
||||
*/
|
||||
export function useGenerateProcurementPlan() {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: (request: GeneratePlanRequest) =>
|
||||
procurementService.generatePlan(request),
|
||||
onSuccess: (data: GeneratePlanResponse) => {
|
||||
// Invalidate relevant queries
|
||||
queryClient.invalidateQueries({ queryKey: procurementKeys.plans() });
|
||||
queryClient.invalidateQueries({ queryKey: procurementKeys.dashboard() });
|
||||
|
||||
// If plan was generated successfully, update the cache
|
||||
if (data.success && data.plan) {
|
||||
queryClient.setQueryData(
|
||||
procurementKeys.plan(data.plan.id),
|
||||
data.plan
|
||||
);
|
||||
|
||||
// Update current plan cache if this is today's plan
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
if (data.plan.plan_date === today) {
|
||||
queryClient.setQueryData(
|
||||
procurementKeys.currentPlan(),
|
||||
data.plan
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to update procurement plan status
|
||||
*/
|
||||
export function useUpdatePlanStatus() {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: ({ planId, status }: { planId: string; status: string }) =>
|
||||
procurementService.updatePlanStatus(planId, status),
|
||||
onSuccess: (updatedPlan: ProcurementPlan) => {
|
||||
// Update the specific plan in cache
|
||||
queryClient.setQueryData(
|
||||
procurementKeys.plan(updatedPlan.id),
|
||||
updatedPlan
|
||||
);
|
||||
|
||||
// Update current plan if this is the current plan
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
if (updatedPlan.plan_date === today) {
|
||||
queryClient.setQueryData(
|
||||
procurementKeys.currentPlan(),
|
||||
updatedPlan
|
||||
);
|
||||
}
|
||||
|
||||
// Invalidate lists to ensure they're refreshed
|
||||
queryClient.invalidateQueries({ queryKey: procurementKeys.plansList() });
|
||||
queryClient.invalidateQueries({ queryKey: procurementKeys.dashboard() });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to trigger the daily scheduler manually
|
||||
*/
|
||||
export function useTriggerDailyScheduler() {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: () => procurementService.triggerDailyScheduler(),
|
||||
onSuccess: () => {
|
||||
// Invalidate all procurement data
|
||||
queryClient.invalidateQueries({ queryKey: procurementKeys.all });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// UTILITY HOOKS
|
||||
// ================================================================
|
||||
|
||||
/**
|
||||
* Hook to check procurement service health
|
||||
*/
|
||||
export function useProcurementHealth() {
|
||||
return useQuery({
|
||||
queryKey: [...procurementKeys.all, 'health'],
|
||||
queryFn: () => procurementService.healthCheck(),
|
||||
staleTime: 60 * 1000, // 1 minute
|
||||
refetchInterval: 5 * 60 * 1000, // Check every 5 minutes
|
||||
});
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// COMBINED HOOKS
|
||||
// ================================================================
|
||||
|
||||
/**
|
||||
* Combined hook for procurement plan dashboard
|
||||
* Fetches current plan, dashboard data, and critical requirements
|
||||
*/
|
||||
export function useProcurementPlanDashboard() {
|
||||
const currentPlan = useCurrentProcurementPlan();
|
||||
const dashboard = useProcurementDashboard();
|
||||
const criticalRequirements = useCriticalRequirements();
|
||||
const health = useProcurementHealth();
|
||||
|
||||
return {
|
||||
currentPlan,
|
||||
dashboard,
|
||||
criticalRequirements,
|
||||
health,
|
||||
isLoading: currentPlan.isLoading || dashboard.isLoading,
|
||||
error: currentPlan.error || dashboard.error || criticalRequirements.error,
|
||||
refetchAll: () => {
|
||||
currentPlan.refetch();
|
||||
dashboard.refetch();
|
||||
criticalRequirements.refetch();
|
||||
health.refetch();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for managing procurement plan lifecycle
|
||||
*/
|
||||
export function useProcurementPlanActions() {
|
||||
const generatePlan = useGenerateProcurementPlan();
|
||||
const updateStatus = useUpdatePlanStatus();
|
||||
const triggerScheduler = useTriggerDailyScheduler();
|
||||
|
||||
return {
|
||||
generatePlan: generatePlan.mutate,
|
||||
updateStatus: updateStatus.mutate,
|
||||
triggerScheduler: triggerScheduler.mutate,
|
||||
isGenerating: generatePlan.isPending,
|
||||
isUpdating: updateStatus.isPending,
|
||||
isTriggering: triggerScheduler.isPending,
|
||||
generateError: generatePlan.error,
|
||||
updateError: updateStatus.error,
|
||||
triggerError: triggerScheduler.error,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user