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,
|
||||
};
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import { RecipesService } from './recipes.service';
|
||||
import { ProductionService } from './production.service';
|
||||
import { OrdersService } from './orders.service';
|
||||
import { SuppliersService } from './suppliers.service';
|
||||
import { ProcurementService } from './procurement.service';
|
||||
|
||||
// Create service instances
|
||||
export const authService = new AuthService();
|
||||
@@ -33,6 +34,7 @@ export const recipesService = new RecipesService();
|
||||
export const productionService = new ProductionService();
|
||||
export const ordersService = new OrdersService();
|
||||
export const suppliersService = new SuppliersService();
|
||||
export const procurementService = new ProcurementService();
|
||||
|
||||
// Export the classes as well
|
||||
export {
|
||||
@@ -48,7 +50,8 @@ export {
|
||||
RecipesService,
|
||||
ProductionService,
|
||||
OrdersService,
|
||||
SuppliersService
|
||||
SuppliersService,
|
||||
ProcurementService
|
||||
};
|
||||
|
||||
// Import base client
|
||||
@@ -73,6 +76,7 @@ export const api = {
|
||||
production: productionService,
|
||||
orders: ordersService,
|
||||
suppliers: suppliersService,
|
||||
procurement: procurementService,
|
||||
} as const;
|
||||
|
||||
// Service status checking
|
||||
@@ -98,6 +102,7 @@ export class HealthService {
|
||||
{ name: 'Suppliers', endpoint: '/suppliers/health' },
|
||||
{ name: 'Forecasting', endpoint: '/forecasting/health' },
|
||||
{ name: 'Notification', endpoint: '/notifications/health' },
|
||||
{ name: 'Procurement', endpoint: '/procurement-plans/health' },
|
||||
];
|
||||
|
||||
const healthChecks = await Promise.allSettled(
|
||||
|
||||
135
frontend/src/api/services/procurement.service.ts
Normal file
135
frontend/src/api/services/procurement.service.ts
Normal file
@@ -0,0 +1,135 @@
|
||||
// ================================================================
|
||||
// frontend/src/api/services/procurement.service.ts
|
||||
// ================================================================
|
||||
/**
|
||||
* Procurement Service - API client for procurement planning endpoints
|
||||
*/
|
||||
|
||||
import { ApiClient } from '../client';
|
||||
import type {
|
||||
ProcurementPlan,
|
||||
GeneratePlanRequest,
|
||||
GeneratePlanResponse,
|
||||
DashboardData,
|
||||
ProcurementRequirement,
|
||||
PaginatedProcurementPlans
|
||||
} from '../types/procurement';
|
||||
|
||||
export class ProcurementService {
|
||||
constructor(private client: ApiClient) {}
|
||||
|
||||
// ================================================================
|
||||
// PROCUREMENT PLAN OPERATIONS
|
||||
// ================================================================
|
||||
|
||||
/**
|
||||
* Get the procurement plan for the current day
|
||||
*/
|
||||
async getCurrentPlan(): Promise<ProcurementPlan | null> {
|
||||
return this.client.get('/procurement-plans/current');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get procurement plan for a specific date
|
||||
*/
|
||||
async getPlanByDate(date: string): Promise<ProcurementPlan | null> {
|
||||
return this.client.get(`/procurement-plans/${date}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get procurement plan by ID
|
||||
*/
|
||||
async getPlanById(planId: string): Promise<ProcurementPlan | null> {
|
||||
return this.client.get(`/procurement-plans/id/${planId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* List procurement plans with optional filters
|
||||
*/
|
||||
async listPlans(params?: {
|
||||
status?: string;
|
||||
startDate?: string;
|
||||
endDate?: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
}): Promise<PaginatedProcurementPlans> {
|
||||
return this.client.get('/procurement-plans/', { params });
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a new procurement plan
|
||||
*/
|
||||
async generatePlan(request: GeneratePlanRequest): Promise<GeneratePlanResponse> {
|
||||
return this.client.post('/procurement-plans/generate', request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update procurement plan status
|
||||
*/
|
||||
async updatePlanStatus(planId: string, status: string): Promise<ProcurementPlan> {
|
||||
return this.client.put(`/procurement-plans/${planId}/status`, null, {
|
||||
params: { status }
|
||||
});
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// REQUIREMENTS OPERATIONS
|
||||
// ================================================================
|
||||
|
||||
/**
|
||||
* Get all requirements for a specific procurement plan
|
||||
*/
|
||||
async getPlanRequirements(
|
||||
planId: string,
|
||||
params?: {
|
||||
status?: string;
|
||||
priority?: string;
|
||||
}
|
||||
): Promise<ProcurementRequirement[]> {
|
||||
return this.client.get(`/procurement-plans/${planId}/requirements`, { params });
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all critical priority requirements
|
||||
*/
|
||||
async getCriticalRequirements(): Promise<ProcurementRequirement[]> {
|
||||
return this.client.get('/procurement-plans/requirements/critical');
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// DASHBOARD OPERATIONS
|
||||
// ================================================================
|
||||
|
||||
/**
|
||||
* Get procurement dashboard data
|
||||
*/
|
||||
async getDashboardData(): Promise<DashboardData | null> {
|
||||
return this.client.get('/procurement-plans/dashboard/data');
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// UTILITY OPERATIONS
|
||||
// ================================================================
|
||||
|
||||
/**
|
||||
* Manually trigger the daily scheduler
|
||||
*/
|
||||
async triggerDailyScheduler(): Promise<{ success: boolean; message: string; tenant_id: string }> {
|
||||
return this.client.post('/procurement-plans/scheduler/trigger');
|
||||
}
|
||||
|
||||
/**
|
||||
* Health check for procurement service
|
||||
*/
|
||||
async healthCheck(): Promise<{
|
||||
status: string;
|
||||
service: string;
|
||||
procurement_enabled: boolean;
|
||||
timestamp: string;
|
||||
}> {
|
||||
return this.client.get('/procurement-plans/health');
|
||||
}
|
||||
}
|
||||
|
||||
// Export singleton instance
|
||||
export const procurementService = new ProcurementService(new ApiClient());
|
||||
@@ -10,4 +10,5 @@ export * from './tenant';
|
||||
export * from './data';
|
||||
export * from './training';
|
||||
export * from './forecasting';
|
||||
export * from './notification';
|
||||
export * from './notification';
|
||||
export * from './procurement';
|
||||
330
frontend/src/api/types/procurement.ts
Normal file
330
frontend/src/api/types/procurement.ts
Normal file
@@ -0,0 +1,330 @@
|
||||
// ================================================================
|
||||
// frontend/src/api/types/procurement.ts
|
||||
// ================================================================
|
||||
/**
|
||||
* TypeScript types for procurement planning API
|
||||
*/
|
||||
|
||||
// ================================================================
|
||||
// BASE TYPES
|
||||
// ================================================================
|
||||
|
||||
export interface ProcurementRequirement {
|
||||
id: string;
|
||||
plan_id: string;
|
||||
requirement_number: string;
|
||||
|
||||
// Product information
|
||||
product_id: string;
|
||||
product_name: string;
|
||||
product_sku?: string;
|
||||
product_category?: string;
|
||||
product_type: string;
|
||||
|
||||
// Quantity requirements
|
||||
required_quantity: number;
|
||||
unit_of_measure: string;
|
||||
safety_stock_quantity: number;
|
||||
total_quantity_needed: number;
|
||||
|
||||
// Current inventory situation
|
||||
current_stock_level: number;
|
||||
reserved_stock: number;
|
||||
available_stock: number;
|
||||
net_requirement: number;
|
||||
|
||||
// Demand breakdown
|
||||
order_demand: number;
|
||||
production_demand: number;
|
||||
forecast_demand: number;
|
||||
buffer_demand: number;
|
||||
|
||||
// Supplier information
|
||||
preferred_supplier_id?: string;
|
||||
backup_supplier_id?: string;
|
||||
supplier_name?: string;
|
||||
supplier_lead_time_days?: number;
|
||||
minimum_order_quantity?: number;
|
||||
|
||||
// Pricing
|
||||
estimated_unit_cost?: number;
|
||||
estimated_total_cost?: number;
|
||||
last_purchase_cost?: number;
|
||||
cost_variance: number;
|
||||
|
||||
// Timing
|
||||
required_by_date: string;
|
||||
lead_time_buffer_days: number;
|
||||
suggested_order_date: string;
|
||||
latest_order_date: string;
|
||||
|
||||
// Status and priority
|
||||
status: string;
|
||||
priority: string;
|
||||
risk_level: string;
|
||||
|
||||
// Purchase tracking
|
||||
purchase_order_id?: string;
|
||||
purchase_order_number?: string;
|
||||
ordered_quantity: number;
|
||||
ordered_at?: string;
|
||||
|
||||
// Delivery tracking
|
||||
expected_delivery_date?: string;
|
||||
actual_delivery_date?: string;
|
||||
received_quantity: number;
|
||||
delivery_status: string;
|
||||
|
||||
// Performance metrics
|
||||
fulfillment_rate?: number;
|
||||
on_time_delivery?: boolean;
|
||||
quality_rating?: number;
|
||||
|
||||
// Approval
|
||||
approved_quantity?: number;
|
||||
approved_cost?: number;
|
||||
approved_at?: string;
|
||||
approved_by?: string;
|
||||
|
||||
// Additional info
|
||||
special_requirements?: string;
|
||||
storage_requirements?: string;
|
||||
shelf_life_days?: number;
|
||||
quality_specifications?: Record<string, any>;
|
||||
procurement_notes?: string;
|
||||
}
|
||||
|
||||
export interface ProcurementPlan {
|
||||
id: string;
|
||||
tenant_id: string;
|
||||
plan_number: string;
|
||||
|
||||
// Plan scope and timing
|
||||
plan_date: string;
|
||||
plan_period_start: string;
|
||||
plan_period_end: string;
|
||||
planning_horizon_days: number;
|
||||
|
||||
// Plan status and lifecycle
|
||||
status: string;
|
||||
plan_type: string;
|
||||
priority: string;
|
||||
|
||||
// Business context
|
||||
business_model?: string;
|
||||
procurement_strategy: string;
|
||||
|
||||
// Plan totals and summary
|
||||
total_requirements: number;
|
||||
total_estimated_cost: number;
|
||||
total_approved_cost: number;
|
||||
cost_variance: number;
|
||||
|
||||
// Demand analysis
|
||||
total_demand_orders: number;
|
||||
total_demand_quantity: number;
|
||||
total_production_requirements: number;
|
||||
safety_stock_buffer: number;
|
||||
|
||||
// Supplier coordination
|
||||
primary_suppliers_count: number;
|
||||
backup_suppliers_count: number;
|
||||
supplier_diversification_score?: number;
|
||||
|
||||
// Risk assessment
|
||||
supply_risk_level: string;
|
||||
demand_forecast_confidence?: number;
|
||||
seasonality_adjustment: number;
|
||||
|
||||
// Execution tracking
|
||||
approved_at?: string;
|
||||
approved_by?: string;
|
||||
execution_started_at?: string;
|
||||
execution_completed_at?: string;
|
||||
|
||||
// Performance metrics
|
||||
fulfillment_rate?: number;
|
||||
on_time_delivery_rate?: number;
|
||||
cost_accuracy?: number;
|
||||
quality_score?: number;
|
||||
|
||||
// Metadata
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
created_by?: string;
|
||||
updated_by?: string;
|
||||
|
||||
// Additional info
|
||||
special_requirements?: string;
|
||||
|
||||
// Relationships
|
||||
requirements: ProcurementRequirement[];
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// REQUEST TYPES
|
||||
// ================================================================
|
||||
|
||||
export interface GeneratePlanRequest {
|
||||
plan_date?: string;
|
||||
force_regenerate?: boolean;
|
||||
planning_horizon_days?: number;
|
||||
include_safety_stock?: boolean;
|
||||
safety_stock_percentage?: number;
|
||||
}
|
||||
|
||||
export interface ForecastRequest {
|
||||
target_date: string;
|
||||
horizon_days?: number;
|
||||
include_confidence_intervals?: boolean;
|
||||
product_ids?: string[];
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// RESPONSE TYPES
|
||||
// ================================================================
|
||||
|
||||
export interface GeneratePlanResponse {
|
||||
success: boolean;
|
||||
message: string;
|
||||
plan?: ProcurementPlan;
|
||||
warnings?: string[];
|
||||
errors?: string[];
|
||||
}
|
||||
|
||||
export interface PaginatedProcurementPlans {
|
||||
plans: ProcurementPlan[];
|
||||
total: number;
|
||||
page: number;
|
||||
limit: number;
|
||||
has_more: boolean;
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// DASHBOARD TYPES
|
||||
// ================================================================
|
||||
|
||||
export interface ProcurementSummary {
|
||||
total_plans: number;
|
||||
active_plans: number;
|
||||
total_requirements: number;
|
||||
pending_requirements: number;
|
||||
critical_requirements: number;
|
||||
|
||||
total_estimated_cost: number;
|
||||
total_approved_cost: number;
|
||||
cost_variance: number;
|
||||
|
||||
average_fulfillment_rate?: number;
|
||||
average_on_time_delivery?: number;
|
||||
|
||||
top_suppliers: Array<Record<string, any>>;
|
||||
critical_items: Array<Record<string, any>>;
|
||||
}
|
||||
|
||||
export interface DashboardData {
|
||||
current_plan?: ProcurementPlan;
|
||||
summary: ProcurementSummary;
|
||||
|
||||
upcoming_deliveries: Array<Record<string, any>>;
|
||||
overdue_requirements: Array<Record<string, any>>;
|
||||
low_stock_alerts: Array<Record<string, any>>;
|
||||
|
||||
performance_metrics: Record<string, any>;
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// FILTER AND SEARCH TYPES
|
||||
// ================================================================
|
||||
|
||||
export interface ProcurementFilters {
|
||||
status?: string[];
|
||||
priority?: string[];
|
||||
risk_level?: string[];
|
||||
supplier_id?: string;
|
||||
product_category?: string;
|
||||
date_range?: {
|
||||
start: string;
|
||||
end: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface RequirementFilters {
|
||||
status?: string[];
|
||||
priority?: string[];
|
||||
product_type?: string[];
|
||||
overdue_only?: boolean;
|
||||
critical_only?: boolean;
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// UI COMPONENT TYPES
|
||||
// ================================================================
|
||||
|
||||
export interface ProcurementPlanCardProps {
|
||||
plan: ProcurementPlan;
|
||||
onViewDetails?: (planId: string) => void;
|
||||
onUpdateStatus?: (planId: string, status: string) => void;
|
||||
showActions?: boolean;
|
||||
}
|
||||
|
||||
export interface RequirementCardProps {
|
||||
requirement: ProcurementRequirement;
|
||||
onViewDetails?: (requirementId: string) => void;
|
||||
onUpdateStatus?: (requirementId: string, status: string) => void;
|
||||
showSupplierInfo?: boolean;
|
||||
}
|
||||
|
||||
export interface ProcurementDashboardProps {
|
||||
showFilters?: boolean;
|
||||
refreshInterval?: number;
|
||||
onPlanGenerated?: (plan: ProcurementPlan) => void;
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// ENUMS
|
||||
// ================================================================
|
||||
|
||||
export enum PlanStatus {
|
||||
DRAFT = 'draft',
|
||||
PENDING_APPROVAL = 'pending_approval',
|
||||
APPROVED = 'approved',
|
||||
IN_EXECUTION = 'in_execution',
|
||||
COMPLETED = 'completed',
|
||||
CANCELLED = 'cancelled'
|
||||
}
|
||||
|
||||
export enum RequirementStatus {
|
||||
PENDING = 'pending',
|
||||
APPROVED = 'approved',
|
||||
ORDERED = 'ordered',
|
||||
PARTIALLY_RECEIVED = 'partially_received',
|
||||
RECEIVED = 'received',
|
||||
CANCELLED = 'cancelled'
|
||||
}
|
||||
|
||||
export enum Priority {
|
||||
CRITICAL = 'critical',
|
||||
HIGH = 'high',
|
||||
NORMAL = 'normal',
|
||||
LOW = 'low'
|
||||
}
|
||||
|
||||
export enum RiskLevel {
|
||||
LOW = 'low',
|
||||
MEDIUM = 'medium',
|
||||
HIGH = 'high',
|
||||
CRITICAL = 'critical'
|
||||
}
|
||||
|
||||
export enum PlanType {
|
||||
REGULAR = 'regular',
|
||||
EMERGENCY = 'emergency',
|
||||
SEASONAL = 'seasonal'
|
||||
}
|
||||
|
||||
export enum ProductType {
|
||||
INGREDIENT = 'ingredient',
|
||||
PACKAGING = 'packaging',
|
||||
SUPPLIES = 'supplies'
|
||||
}
|
||||
Reference in New Issue
Block a user